#include "SSVContainer.h"

#include <uam/ServerTimeMgr.h>

#include <algorithm>

#include "ABSBondInfo.h"
#include "BondCDCPriceInfo.h"
#include "BondDict.h"
#include "BondInfo.h"
#include "BondMarketStream.h"
#include "CompanyReport.h"
#include "SSBankQuote.h"
#include "SSSortInfo.h"

#ifndef WIN32
#define _TRUNCATE ((size_t) - 1)
#endif

extern void _SplitStr(std::vector<std::string>& dst, const std::string& src,
                      const std::string& seps);

namespace {
inline bool IsEmpty(const char* str) {
  // 旧代码是 strlen(str)<=0;
  return str == nullptr || *str == '\0';
}
inline bool IsNullPrice(const char* price) {
  // price:来自PRICE.m_sPrice,"--" 也算无效报价
  return IsEmpty(price) || *price == '-';
}
inline bool IsReportPriceHasNumber(const PRICE& price) {
  // 报价包含确切的数字
  return !((!IsEmpty(price.m_quotetype) && atoi(price.m_quotetype) == 0) ||
           IsEmpty(price.m_yield_price) ||
           strcmp(price.m_price_status, "0") == 0 ||
#ifdef WIN32
           qstricmp(price.m_sPrice, "Ofr") == 0 ||
           qstricmp(price.m_sPrice, "Bid") == 0
#else
           strcasecmp(price.m_sPrice, "Ofr") == 0 ||
           strcasecmp(price.m_sPrice, "Bid") == 0
#endif
  );
}
inline bool CheckPriceByOp(const char* price, const char* szBegin,
                           const char* szEnd, int op) {
  float fBid = atof(price);

  bool bRet = false;
  if (!IsEmpty(szBegin) && !IsEmpty(szEnd)) {
    bRet = (fBid > (atof(szBegin) - 0.00001));
    if (bRet) bRet = (fBid < (atof(szEnd) + 0.00001));
  } else {
    if (!IsEmpty(szBegin)) bRet = (fBid > (atof(szBegin) - 0.00001));

    if (!bRet && !IsEmpty(szEnd)) bRet = (fBid < (atof(szEnd) + 0.00001));
  }

  return bRet;
}

inline bool CheckBpPriceByOp(const char* price0, const char* price1,
                             double diff) {
  // 将价格price与指定值diff进行对比,检测通过返回true;
  if (price0[0] != '\0') {
    if (diff < atof(price0) - 1e-6) return false;
  }
  if (price1[0] != '\0') {
    if (diff > atof(price1) + 1e-6) return false;
  }
  return true;
}

inline bool CheckReportPrice(const PRICE& price, const char* filterRangeBegin,
                             const char* filterRangeEnd, int op) {
  // 核查bid或者ofr是否在指定范围之内
  if (IsEmpty(filterRangeBegin) && IsEmpty(filterRangeEnd)) return true;
  // 如果Bid/Ofr后的edit不为空,但是报价中价格为空,那么不显示
  if (!IsReportPriceHasNumber(price)) return false;

  return CheckPriceByOp(price.m_yield_price, filterRangeBegin, filterRangeEnd,
                        op);
}

bool DecodeAsDouble(const char* str, double& dvalue) {
  if (!IsEmpty(str)) {
    dvalue = atof(str);
    if (dvalue == 0.0) {
      if (str[0] == '.' || (str[0] >= '0' && str[0] <= '9')) return true;
      return false;
    }
    return true;
  }
  return false;
}
class MarketStreamPriceMap {
  typedef map<string, double> PriceMap;
  int m_corp;           // 公司id,与'c','e'进行比较
  bool m_init;          // 是否已经初始化了
  bool m_cfets;         // true 表示使用AfxGetCFETSMarketStream
  PriceMap m_pricemap;  // 价格表,避免list遍历查找
 public:
  MarketStreamPriceMap(int nCorp, bool cfets) : m_corp(nCorp), m_init(false) {}
  MarketStreamPriceMap(const CMarketStreamlst& stList)
      : m_init(true), m_cfets(false), m_corp(0) {
    for (std::list<MarketStreamInfo>::const_iterator it =
             stList.m_list.cbegin();
         it != stList.m_list.cend(); ++it) {
      const MarketStreamInfo& info = *it;
      char keybuf[128] = {0};
      FMTBUF(keybuf, "%s.%s-%s", info.m_body.m_bondkey,
             info.m_body.m_listedmarket, info.m_company_id);
      string key = keybuf;
      if (m_pricemap.find(key) != m_pricemap.end()) continue;
      m_pricemap[key] = atof(info.m_body.m_price);
    }
  }
  bool FindPrice(const char* pszKey, const char* pszMarket,
                 const char* brokerid, double& price) {
    if (!m_init) {
      m_init = true;
      Init();
    }
    if (m_pricemap.empty() || pszKey == 0 || pszMarket == 0 || brokerid == 0)
      return false;
    char keybuf[128] = {0};
    FMTBUF(keybuf, "%s.%s-%s", pszKey, pszMarket, brokerid);
    PriceMap::iterator it = m_pricemap.find(keybuf);
    if (it != m_pricemap.end()) {
      price = it->second;
      return true;
    }
    return false;
  }

 protected:
  void Init() {
    // 旧代码调用AfxGetCFETSMarketStream().GetLastDayMarketStreamByCorp
    // 来获取CMarketStreamlst,会对参数m_corp进行c,e检查,通过后返回当天的所有成交信息
    if (m_corp != 'c' && m_corp != 'e') return;
    CMarketStream* ms = m_cfets ? &CMarketStream::cfectsStream()
                                : &CMarketStream::exchangeStream();
    FOR_EACH_MARKETSTREAM_EX(ms, 0, it) { AddPrice(*it); }
  }
  void AddPrice(const MarketStreamInfo& info) {
    char keybuf[128] = {0};
    FMTBUF(keybuf, "%s.%s-%s", info.m_body.m_bondkey,
           info.m_body.m_listedmarket, info.m_company_id);
    string key = keybuf;
    if (m_pricemap.find(key) == m_pricemap.end())
      m_pricemap[key] = atof(info.m_body.m_price);
  }
};

class RatingRankManager {
  typedef std::map<string, int> RankMap;
  bool m_initialized;
  std::mutex m_init_lock;
  RankMap m_rankmap;

 public:
  static RatingRankManager& Get() {
    static RatingRankManager rrm;
    return rrm;
  }
  RatingRankManager() : m_initialized(false) {}
  int GetRatingRank(const std::string& sRating) {
    if (!m_initialized) {
      std::lock_guard<std::mutex> locker(m_init_lock);
      if (!m_initialized) {
        Init();
        m_initialized = true;
      }
    }
    RankMap::const_iterator pos = m_rankmap.find(sRating);
    if (pos != m_rankmap.end()) {
      return pos->second;
    }
    return -1;
  }

 protected:
  void Init() {
    int nIndex = 0;
    m_rankmap[""] = nIndex;
    m_rankmap["--"] = nIndex;
    m_rankmap["CCL"] = nIndex++;
    m_rankmap["D"] = nIndex++;
    m_rankmap["C-3"] = nIndex++;
    m_rankmap["C-2"] = nIndex++;
    m_rankmap["C-"] = nIndex++;
    m_rankmap["C-"] = nIndex++;
    m_rankmap["C"] = nIndex++;
    m_rankmap["C+"] = nIndex++;
    m_rankmap["CC-"] = nIndex++;
    m_rankmap["CC"] = nIndex++;
    m_rankmap["CC+"] = nIndex++;
    m_rankmap["CCC-"] = nIndex++;
    m_rankmap["C-1"] = nIndex++;
    m_rankmap["CCC"] = nIndex++;
    m_rankmap["CCC+"] = nIndex++;
    m_rankmap["B-3"] = nIndex++;
    m_rankmap["B-2"] = nIndex++;
    m_rankmap["B-"] = nIndex++;
    m_rankmap["B"] = nIndex++;
    m_rankmap["B+"] = nIndex++;
    m_rankmap["BB-"] = nIndex++;
    m_rankmap["BB"] = nIndex++;
    m_rankmap["BB+"] = nIndex++;
    m_rankmap["BBB-"] = nIndex++;
    m_rankmap["B-1"] = nIndex++;
    m_rankmap["BBB"] = nIndex++;
    m_rankmap["BBB+"] = nIndex++;
    m_rankmap["A-3"] = nIndex++;
    m_rankmap["A-2"] = nIndex++;
    m_rankmap["A-"] = nIndex++;
    m_rankmap["A"] = nIndex++;
    m_rankmap["A+"] = nIndex++;
    m_rankmap["AA-"] = nIndex++;
    m_rankmap["AA2"] = nIndex++;
    m_rankmap["AA(2)"] = nIndex++;
    m_rankmap["AA"] = nIndex++;
    m_rankmap["AA+"] = nIndex++;
    m_rankmap["AAA-"] = nIndex++;
    m_rankmap["A-1"] = nIndex++;
    m_rankmap["AAA"] = nIndex++;
    m_rankmap["AAA+"] = nIndex++;  // AAA+ > AAA > A-1 > AAA- > AA+ > AA > AA- >
                                   // A+ > A > A- > A-2 > A-3 > BBB+ > BBB
  }
};
inline int GetBondIndex(const BrokerKey& s) { return s.m_nIndex; }
#define GetBrokid(/*const BrokerKey&*/ s) s.GetBrokerId()
// 注意,这里返回int值,但是下面使用需要比较nRank1<nRank1,等价于nRank1-nRank2<0;
int CompareRankWithIssuerRating(CBondContainer& container,
                                const BrokerKey& str1, const BrokerKey& str2) {
  int nRank1 = RatingRankManager::Get().GetRatingRank(
      (container.ElementAtR(GetBondIndex(str1))).GetIssuerRatingEx());
  int nRank2 = RatingRankManager::Get().GetRatingRank(
      (container.ElementAtR(GetBondIndex(str2))).GetIssuerRatingEx());
  return nRank1 - nRank2;
}
int CompareRankWithBondRating(CBondContainer& container, const BrokerKey& str1,
                              const BrokerKey& str2) {
  int nRank1 = RatingRankManager::Get().GetRatingRank(
      (container.ElementAtR(GetBondIndex(str1))).GetBondRating());
  int nRank2 = RatingRankManager::Get().GetRatingRank(
      (container.ElementAtR(GetBondIndex(str2))).GetBondRating());
  return nRank1 - nRank2;
}
enum kQuoteFildType {
  kQuoteFildTypeBidVol,
  kQuoteFildTypeBidNetPrice,
  kQuoteFildTypeBid,
  kQuoteFildTypeOfrVol,
  kQuoteFildTypeOfrNetPrice,
  kQuoteFildTypeOfr
};
float GetBkQuoteValue(const BrokerKey& bkey, kQuoteFildType type) {
  float fvalue = 0.00;
  BKQUOTE bkquote;
  CBondBankRep* report = CBondContainer::instance().GetClntRep(bkey.m_nIndex);
  if (report && report->GetBankRepByKey(bkey.GetBrokerId(), bkquote)) {
    switch (type) {
      case kQuoteFildTypeBidVol:
        if (abs(atoi(bkquote.m_BidStatus)) == 1)
          fvalue = atof(bkquote.m_BidVol);
        break;
      case kQuoteFildTypeBidNetPrice:
        if (abs(atoi(bkquote.m_BidStatus)) == 1)
          fvalue = atof(bkquote.m_BidClean);
        break;
      case kQuoteFildTypeBid:
        if (abs(atoi(bkquote.m_BidStatus)) == 1) fvalue = atof(bkquote.m_Bid);
        break;
      case kQuoteFildTypeOfrVol:
        if (abs(atoi(bkquote.m_OfrStatus)) == 1)
          fvalue = atof(bkquote.m_BidVol);
        break;
      case kQuoteFildTypeOfrNetPrice:
        if (abs(atoi(bkquote.m_OfrStatus)) == 1)
          fvalue = atof(bkquote.m_OfrClean);
        break;
      case kQuoteFildTypeOfr:
        if (abs(atoi(bkquote.m_OfrStatus)) == 1) fvalue = atof(bkquote.m_Ofr);
        break;
    }
  }
  return 0.00;
}
time_t GetBkQuoteTime(const BrokerKey& bkey) {
  CBondBankRep* report = CBondContainer::instance().GetClntRep(bkey.m_nIndex);
  if (report) {
    BKQUOTE bkquote;
    if (report->GetBankRepByKey(bkey.GetBrokerId(), bkquote)) {
      return bkquote.m_Time;
    }
  }
  return 0;
}

}  // namespace

CSSVContainer::CSSVContainer()
    : m_keymap_dirty(false), m_keymap(StringPtrMap::kKeyModeAsKey) {
  m_ContainerType = BROKER_CONTAINER;
  m_bLockTop = false;
  m_sort_key = VMODIFY_TIME;
  m_nNumTotalQuote = 0;
  m_nNumDiff2CDC = 0;

  m_bDesc = false;
  m_bDataChanged = false;

  m_pSortBondMng = nullptr;
  m_mapPerBondKey.clear();
}

CSSVContainer::CSSVContainer(const CSSVContainer& src)
    : m_keymap_dirty(false), m_keymap(StringPtrMap::kKeyModeAsKey) {
  m_ContainerType = BROKER_CONTAINER;
  m_bLockTop = false;
  m_sort_key = VMODIFY_TIME;
  m_nNumTotalQuote = 0;
  m_nNumDiff2CDC = 0;
  m_bDesc = false;
  m_bDataChanged = true;
  m_pSortBondMng = nullptr;
}

int CSSVContainer::CalMaturityTerm(
    const std::string& sPrePeriod) {  // 用于期限排序
  string sPeriod = sPrePeriod;
  if (sPeriod.empty()) return -1;

  size_t pos = sPeriod.find("+");
  if (pos >= 2) sPeriod = sPeriod.substr(0, pos);
  if (sPeriod[sPeriod.length() - 1] == 'Y' ||
      sPeriod[sPeriod.length() - 1] == 'y') {
    return atof(sPeriod.substr(0, sPeriod.length() - 1).c_str()) * 365;
  } else if (sPeriod[sPeriod.length() - 1] == 'M' ||
             sPeriod[sPeriod.length() - 1] == 'm') {
    return atof(sPeriod.substr(0, sPeriod.length() - 1).c_str()) * 30;
  } else if (sPeriod[sPeriod.length() - 1] == 'W' ||
             sPeriod[sPeriod.length() - 1] == 'w') {
    return atof(sPeriod.substr(0, sPeriod.length() - 1).c_str()) * 7;
  } else if (sPeriod[sPeriod.length() - 1] == 'D' ||
             sPeriod[sPeriod.length() - 1] == 'd') {
    return atof(sPeriod.substr(0, sPeriod.length() - 1).c_str());
  } else
    return -999;
}

int CSSVContainer::CalMaturityType(
    const std::string&
        sPrePeriod) {  // 用于期限排序，当用CalMaturityTerm计算出的结果相同时，使其按照“年/月/周/日”的顺序排列
  string sPeriod = sPrePeriod;
  if (sPeriod.empty()) return -1;

  size_t pos = sPeriod.find("+");
  if (pos >= 2) sPeriod = sPeriod.substr(0, pos - 1);
  if (sPeriod[sPeriod.length() - 1] == 'Y' ||
      sPeriod[sPeriod.length() - 1] == 'y') {
    return 4;
  } else if (sPeriod[sPeriod.length() - 1] == 'M' ||
             sPeriod[sPeriod.length() - 1] == 'm') {
    return 3;
  } else if (sPeriod[sPeriod.length() - 1] == 'W' ||
             sPeriod[sPeriod.length() - 1] == 'w') {
    return 2;
  } else if (sPeriod[sPeriod.length() - 1] == 'D' ||
             sPeriod[sPeriod.length() - 1] == 'd') {
    return 1;
  } else
    return -999;
}

CSSVContainer::~CSSVContainer() {
  Clear();
  m_mapPerBondKey.clear();
}

CSSVContainer& CSSVContainer::availableBond() {
  static CSSVContainer s_ab;
  return s_ab;
}

CSSVContainer& CSSVContainer::availableAbsBond() {
  static CSSVContainer s_abs;
  return s_abs;
}

CSSVContainer& CSSVContainer::availableExBond() {
  static CSSVContainer s_ex;
  return s_ex;
}

bool CSSVContainer::Clear() {
  std::lock_guard<std::mutex> locker(m_mutex);
  m_array_result.clear();
  MarkMapDirty();
  m_brokevec.m_vct.clear();
  m_keymap.RemoveAll();

  m_bDataChanged = true;
  return true;
}

int CSSVContainer::GetSize() const { return m_array_result.size(); }

int CSSVContainer::GetAllBondsSize() {
  return CBondContainer::instance().GetSize();
}

bool CSSVContainer::SetMap() {
  /*
          不少场景,是不需通过key来查找债券索引
          因此,把原先SetMap中map<key,index>的建立的过程推迟到需要的时候
          每次访问m_keymap之前都必须PrepareMap
          如果已经准备好,那么PrepareMap就是直接为空返回

          CBondContainer中使用的是StringPtrMap
  */
  MarkMapDirty();
  return true;
}
bool CSSVContainer::SetMapImpl() {
  std::lock_guard<std::mutex> locker(m_mutex);

  m_keymap.RemoveAll();

  int nsize = GetSize();
  if (nsize == 0) return true;

  m_keymap.InitHashTable(nsize + 10);

  class BondKeyGen {
    enum { KEYSIZE = sizeof(tBondKey) + sizeof(tListedMarket) + 12 };
    char m_buf[KEYSIZE + 1];

   public:
    BondKeyGen() { m_buf[0] = 0; }
    void Set(const char* bondKey, const char* listedMarket) {
      int bn = strlen(bondKey);
      bn = bn < KEYSIZE ? bn : KEYSIZE;
      int mn = strlen(listedMarket);
      mn = mn < (KEYSIZE - bn - 1) ? mn : (KEYSIZE - bn - 1);
      if (bn > 0) memcpy(m_buf, bondKey, bn);
      if (mn > 0) {
        m_buf[bn] = '.';
        memcpy(m_buf + bn + 1, listedMarket, mn);
        m_buf[mn + bn + 1] = 0;
      } else
        m_buf[bn] = 0;
    }
    const char* c_str() const { return m_buf; }
  };
  BondKeyGen sKey;
  for (int i = 0; i < nsize; i++) {
    const CBondInfo& info = ElementAt2(i);
    if (!info.IsValidBond()) continue;
    sKey.Set(info.GetBondKey(), info.GetListedMarket());
    m_keymap.SetAt(sKey.c_str(), (void*)i);
  }
  return true;
}
void CSSVContainer::PrepareMap() {
  if (m_keymap_dirty) {
    m_keymap_dirty = false;
    SetMapImpl();
  }
}
bool CSSVContainer::AddBondByID(int nBondIndex) {
  return AddBond(nBondIndex);

  // 	if(nIndex < 0)return false;
  // 	m_array_result.push_back(nIndex);
  // 	return true;
}

bool CSSVContainer::AddBondByKey(const char* sBondKey,
                                 const char* sListedMarket) {
  return AddBond(sBondKey, sListedMarket);

  // 	//@modify by Tony 2015.2.15 采用新接口
  // 	int id = CBondContainer::instance().GetBondIndex(sBondKey,
  // sListedMarket);
  //
  // 	return AddBondByID(id);
}

bool CSSVContainer::RemoveBondByID(int nIndex) {
  //@add by ziegxu 2015.7.27
  if (nIndex < 0) return true;
  std::vector<int>::iterator it;
  for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
    if (*it == nIndex) {
      it = m_array_result.erase(it);
      MarkMapDirty();
      break;
    }
  }
  return true;
}

bool CSSVContainer::RemoveBondByKey(const char* sBondKey,
                                    const char* sListedMarket) {
  // 	int id = -1;
  // 	CBondInfo &info = CBondContainer::instance().GetBondInfoByKey(sBondKey,
  // sListedMarket, &id);

  //@modify by Tony 2015.2.15 采用新接口
  int id = CBondContainer::instance().GetBondIndex(sBondKey, sListedMarket);
  if (id < 0) return true;
  std::vector<int>::iterator it;
  for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
    if (*it == id) {
      it = m_array_result.erase(it);
      MarkMapDirty();
      break;
    }
  }
  return true;
}

bool CSSVContainer::SetContainerType(int containerType) {
  m_ContainerType = containerType;
  return true;
}

bool CSSVContainer::SetLockTop(bool bLockTop) {  // 设置锁定置顶
  m_bLockTop = bLockTop;
  return true;
}

bool CSSVContainer::SetContent(BLHCONDITION& condStr, bool bAll) {
  std::vector<int>::iterator itr = m_array_result.begin();
  m_brokevec.m_vct.clear();
  m_bDataChanged = true;
  if (condStr.nHasFlg == 0) {
    // 所有报价
    char szkey[10] = {0};
    memset(szkey, 0, sizeof(szkey));
    for (; itr != m_array_result.end(); itr++) {
      int nTmpKey = *itr;
      if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize()) continue;

      if (bAll) {  // 所有经纪商
        int nSize = sizeof(condStr.nBrokId) / sizeof(UINT);
        for (int i = 0; i < nSize; i++) {
          if (condStr.nBrokId[i] == 0x00) break;

          // 先快速检查看几个控件对应的过滤器值是否全部为空,可以避免GetCompanyInfoById的开销
          bool szkey_ok = false;
          bool need_show = condStr.IsPriceNeedShowFastCheck();
          if (!need_show) {
            szkey_ok = true;
            memset(szkey, 0, sizeof(szkey));
#ifdef WIN32
            _itoa_s(condStr.nBrokId[i], szkey, 10, 10);
#else
            sprintf(szkey, "%u", condStr.nBrokId[i]);
#endif
            REPORT rpt = {0};
            if (CBondContainer::instance().GetCompanyInfoById(szkey, nTmpKey,
                                                              rpt)) {
              if (IsPriceNeedShow(condStr, rpt, nTmpKey,
                                  false))  // 无需检查是否是有效报价,提升速度
              {
                need_show = true;
              }
            }
          }

          if (need_show) {
            if (!szkey_ok) {
              memset(szkey, 0, sizeof(szkey));

#ifdef WIN32
              _itoa_s(condStr.nBrokId[i], szkey, 10, 10);
#else
              sprintf(szkey, "%u", condStr.nBrokId[i]);
#endif
            }
            m_brokevec.m_vct.emplace_back(BrokerKey(szkey, nTmpKey));
          }
        }
      } else {  // 单个经纪商
        m_brokevec.m_vct.emplace_back(BrokerKey(condStr.sCompanyid, nTmpKey));
      }
    }
    return true;
  }

  class BondReportCallback : public CBondCompanyRep::ApplyCallback {
    bool m_all;
    SSBrokerKeyVector& m_brokevec;
    const BLHCONDITION& m_cond;
    int m_index;

   public:
    BondReportCallback(SSBrokerKeyVector& brokevec, const BLHCONDITION& condStr,
                       bool all)
        : m_brokevec(brokevec), m_cond(condStr), m_index(-1), m_all(all) {}

    void Collect(int index, CBondCompanyRep* prep) {
      m_index = index;

      if (prep) prep->ApplyAccess(m_all, m_cond.sCompanyid, this);
    }

    virtual bool DoAccess(const REPORT& rept) {
      if (m_all) {
        int nCorpID = atoi(rept.m_company_id);
        if (!((nCorpID > 0 && nCorpID <= 6) ||
              nCorpID == 98))  // TODO validbroker
          return true;         // 过滤非Broker
      }

      if (IsPriceNeedShow(m_cond, rept, m_index, true)) {
        m_brokevec.m_vct.emplace_back(BrokerKey(rept.m_company_id, m_index));
      }
      return true;
    }
  };
  // 有效报价
  BondReportCallback accessor(m_brokevec, condStr, bAll);
  for (int i = 0; itr != m_array_result.end(); itr++, i++) {
    int nTmpKey = *itr;
    if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize()) continue;
    accessor.Collect(nTmpKey, GetCompanyRep(i));
  }
  return true;
}

bool CSSVContainer::Retrieve(BLHCONDITION& condStr, bool bAll,
                             CSSVContainer* pVC, bool bSecondaryMarket) {
  if (!pVC) return RetrieveFromStatic(condStr, bAll);

  Clear();
  m_lcond = condStr;
  pVC->Retrieve(condStr, m_array_result, bSecondaryMarket);
  SetMap();
  SetContent(condStr, bAll);
  return true;
}

bool CSSVContainer::RetrieveFromStatic(BLHCONDITION& condStr, bool bAll) {
  Clear();
  m_lcond = condStr;
  CBondContainer::instance().RetrieveFromStatic(condStr, m_array_result);
  SetMap();

  SetContent(condStr, bAll);
  return true;
}

bool CSSVContainer::Retrieve(int nType, const char* szType,
                             CSSVContainer* pVC) {
  Clear();
  if (!pVC)
    CBondContainer::instance().RetrieveFromStatic(nType, szType,
                                                  m_array_result);
  else
    pVC->RetrieveFromStatic(nType, szType, m_array_result);

  SetMap();

  BLHCONDITION condStr;
  SetContent(condStr, false);
  return true;
}

bool CSSVContainer::Retrieve(int nType, const char* szType,
                             std::list<std::string>& m_brokls,
                             CSSVContainer* pVC) {
  Clear();
  if (!Retrieve(nType, szType, pVC)) return false;
  SetContent(m_brokls);
  return true;
}

bool CSSVContainer::Retrieve(int nType, const char* szType,
                             BLHCONDITION& condStr, CSSVContainer* pVC) {
  Clear();
  if (!Retrieve(nType, szType, pVC)) return false;
  SetContent(condStr, false);
  return true;
}
bool CSSVContainer::IsBondPassCondition(int nIndex, const BLHCONDITION& condStr,
                                        bool bSecondaryMarket,
                                        bool bAttention) {
  // by scofined.qi ,将bool CSSVContainer::Retrieve( BLHCONDITION & condStr,
  // std::vector<int> & array_result, bool bSecondaryMarket)
  // 里的逻辑抽取出来作为静态函数,可提供给外部使用;
  //
  // 删除报价相关筛选，edit by Lance，2021.8.20
  CBondContainer& gc = CBondContainer::instance();
  if (!gc.IsValidIndex(nIndex)) return false;
  const CBondInfo& info = gc.ElementAtR(nIndex);
  bool passed = false;
  do {
    if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
      break;
    if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
      break;
    if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
      break;
    if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
      break;
    if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
      break;
    if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
      break;
    if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
        !info.CheckCommonUseType(condStr))  // 常用
      break;
    if (condStr.nType[0] != CBondContainer::BondAll &&
        !info.CheckBondType(condStr))  // 产品
      break;
    if (condStr.nGSMType[0] != CBondContainer::BondC_All &&
        !info.CheckGSMBondType(condStr))  // 公募私募产品类型
      break;
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
        !gc.GetMultiLevel(condStr, info))  // 主体评级
      break;

    if (condStr.nOutlookRating[0] != CBondContainer::OutlookRatingAll &&
        !gc.GetOutlookRatingLevel(condStr, info))
      break;

    if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll &&
        !gc.GetCDCRatingLevel(condStr, info))  // 中债隐含
      break;
    if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll &&
        !gc.GetCSIRatingLevel(condStr, info))  // 中证隐含
      break;
    if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll &&
        !gc.GetCBRRatingLevel(condStr, info))  // 中债资信
      break;

    if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
        !gc.GetWarrType(condStr, info))  // 有担保
      break;
    if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
        !gc.GetMultiCouponType(condStr, info))  // 特殊分类
      break;
    if (condStr.nRight != CBondContainer::RightAll &&
        gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
      break;
    if (condStr.nRightEx[0] != CBondContainer::RightExAll &&
        !info.CheckRightEx(condStr))  // 含权类型
      break;
    if (condStr.nRange[0] != CBondContainer::RangeAll &&
        !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
      break;
    if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
        !gc.GetMunicpType(condStr, info))  // 城投
      break;
    if (condStr.nInterbank != 0 && !info.IsInterbank())  // 银行间
      break;
    if (condStr.nExchange != 0 && !info.IsExchange())  // 交易所
      break;
    if (condStr.nInstion[0] != CBondContainer::InstAll &&
        !gc.GetMultiInstion(condStr, info))  // 机构类型
      break;
    if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr))  // 发行人
      break;
    if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
      break;
    if (condStr.szSector2021[0][0] != '\0' &&
        !info.CheckSector2021(condStr))  // 行业
      break;
    if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
      break;
    if (condStr.szSubType[0][0] != '\0' &&
        !info.CheckBontSubType(condStr))  // 细分
      break;
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
        !info.CheckDebtRating(condStr))  // 债项评级
      break;
    if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
        !info.CheckFinDebt(condStr))  // 金融债
      break;
    if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
        !gc.IsPlatformType(condStr, info))  // 平台债
      break;
    if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
        !gc.IsLocalBond(condStr, info))  // 地方债
      break;
    //  add  by  lbl  NCD
    if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
        !info.CheckNCDRating(condStr))  // NCD
      break;
    // end
    if (condStr.nIssueYear[0] != 0 &&
        !info.CheckIssueYear(condStr))  // 发行年份
      break;
    if (condStr.nStateType != 0 &&
        !gc.GetStateType(
            condStr, info))  // 0=全部，1=今日簿记建档，2=当日发行，3=当日公告
      break;
    // if(condStr.nUnderwriter != 0 && info.m_sIsUnderwriter!='1')
    //	break;
    if (strlen(condStr.szIssueDateB) != 0 &&
        strlen(condStr.szIssueDateE) != 0 &&
        !gc.GetIssueStartDate(condStr, info))  // 发行日期
      break;
    if (condStr.szUnderwriter[0] != 0 &&
        !info.CheckUnderwriter(condStr))  // 在团
      break;
    if (condStr.nCreditBond != 0 &&
        !info.IsCreditBond(condStr))  // 信用债,利率债
      break;
    if (!info.IsInDays(condStr)) break;
    if (condStr.nDeadLineRange[0] != CBondContainer::DL_RangeAll &&
        !gc.GetDeadLineRange(condStr, info))  // 期限筛选
      break;
    if (condStr.nExchangeType != CBondContainer::kExchAll &&
        !gc.GetExchangeType(condStr, info))  // 交易所类型
      break;

    if (condStr.nETSBond[0] != CBondContainer::ETSBondAll &&
        !gc.IsETSBondType(condStr, info))  // 永续债
      break;
    if (condStr.nCorpBond[0] != CBondContainer::CorpBondAll &&
        !gc.IsCorpBondType(condStr, info))  // 公司债
      break;
    if (condStr.nAssetStatus[0] != CBondContainer::AssetAll &&
        !info.CheckAssetStatus(condStr))  // 发行
      break;
    if (condStr.nExpireInHoliday == 1 && info.IsExpireInHoliday())  // 不含假期
      break;
    /*TODO:
    if (condStr.sBondLiquidity[0] != '\0' &&
    !AfxGetBondLiquidity().CheckLiquidity(nIndex, condStr))//债券流动性 break;
    if (condStr.sIssuerLiquidity[0] != '\0' &&
    !AfxGetIssuerLiquidity().CheckLiquidity(nIndex, condStr))//主体流动性 break;
    if (condStr.nPrincipalPayType[0] != '\0' && condStr.nPrincipalPayType[0] !=
    CBondContainer::PPTAll && !gc.CheckPrincipalPayType(condStr,
    info))//偿还方式 break; if (condStr.nHighYieldBond[0] != '\0' &&
    condStr.nHighYieldBond[0] != CBondContainer::HYBAll &&
    !AfxGetHighYieldBond().CheckHighYieldBond(nIndex, condStr))//高收益债 break;
    */
    passed = true;
  } while (0);
  return passed;
}

bool CSSVContainer::IsSSEFIBondPassCondition(int nIndex,
                                             const BLHCONDITION& condStr,
                                             bool bSecondaryMarket) {
  // by scofined.qi ,将bool CSSVContainer::Retrieve( BLHCONDITION & condStr,
  // std::vector<int> & array_result, bool bSecondaryMarket)
  // 里的逻辑抽取出来作为静态函数,可提供给外部使用;
  //
  // 删除报价相关筛选，edit by Lance，2021.8.20
  CBondContainer& gc = CBondContainer::instance();
  if (!gc.IsValidIndex(nIndex)) return false;
  const CBondInfo& info = gc.ElementAtR(nIndex);
  bool passed = false;
  do {
    if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
      break;
    if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
      break;
    if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
      break;
    if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
      break;
    if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
      break;
    if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
      break;
    if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
        !info.CheckCommonUseType(condStr))  // 常用
      break;
    if (condStr.nType[0] != CBondContainer::BondAll &&
        !info.CheckBondTypeV2(condStr))  // 产品
      break;
    if (condStr.nGSMType[0] != CBondContainer::BondC_All &&
        !info.CheckGSMBondType(condStr))  // 公募私募产品类型
      break;
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
        !gc.GetMultiLevel(condStr, info))  // 主体评级
      break;
    if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
        !gc.GetWarrType(condStr, info))  // 有担保
      break;
    if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
        !gc.GetMultiCouponType(condStr, info))  // 特殊分类
      break;
    if (condStr.nRight != CBondContainer::RightAll &&
        gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
      break;
    if (condStr.nRightEx[0] != CBondContainer::RightExAll &&
        !info.CheckRightEx(condStr))
      break;
    if (condStr.nRange[0] != CBondContainer::RangeAll &&
        !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
      break;
    if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
        !gc.GetMunicpType(condStr, info))  // 城投
      break;
    if (condStr.nInterbank != 0 && !info.IsInterbank())  // 银行间
      break;
    if (condStr.nExchange != 0 && !info.IsExchange())  // 交易所
      break;
    if (condStr.nInstion[0] != CBondContainer::InstAll &&
        !gc.GetMultiInstion(condStr, info))  // 机构类型
      break;
    if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr))  // 发行人
      break;
    if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
      break;
    if (condStr.szSector2021[0][0] != '\0' &&
        !info.CheckSector2021(condStr))  // 行业
      break;
    if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
      break;
    if (condStr.szSubType[0][0] != '\0' &&
        !info.CheckBontSubType(condStr))  // 细分
      break;
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
        !info.CheckDebtRating(condStr))  // 债项评级
      break;
    if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
        !info.CheckFinDebt(condStr))  // 金融债
      break;
    if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
        !gc.IsPlatformType(condStr, info))  // 平台债
      break;
    if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
        !gc.IsLocalBond(condStr, info))  // 地方债
      break;
    //  add  by  lbl  NCD
    if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
        !info.CheckNCDRating(condStr))  // NCD
      break;
    // end
    if (condStr.nIssueYear[0] != 0 &&
        !info.CheckIssueYear(condStr))  // 发行年份
      break;
    if (condStr.nStateType != 0 &&
        !gc.GetStateType(
            condStr, info))  // 0=全部，1=今日簿记建档，2=当日发行，3=当日公告
      break;
    if (strlen(condStr.szIssueDateB) != 0 &&
        strlen(condStr.szIssueDateE) != 0 &&
        !gc.GetIssueStartDate(condStr, info))  // 发行日期
      break;
    if (condStr.szUnderwriter[0] != 0 &&
        !info.CheckUnderwriter(condStr))  // 在团
      break;
    if (condStr.nCreditBond != 0 &&
        !info.IsCreditBond(condStr))  // 信用债,利率债
      break;
    if (!info.IsInDays(condStr)) break;
    if (condStr.nDeadLineRange[0] != CBondContainer::DL_RangeAll &&
        !gc.GetDeadLineRange(condStr, info))  // 期限筛选
      break;
    if (condStr.nExchangeType != CBondContainer::kExchAll &&
        !gc.GetExchangeType(condStr, info))  // 交易所类型
      break;
    if (condStr.nETSBond[0] != CBondContainer::ETSBondAll &&
        !gc.IsETSBondType(condStr, info))  // 永续债
      break;
    if (condStr.nCorpBond[0] != CBondContainer::CorpBondAll &&
        !gc.IsCorpBondType(condStr, info))  // 公司债
      break;
    if (condStr.nAssetStatus[0] != CBondContainer::AssetAll &&
        !info.CheckAssetStatus(condStr))  // 发行
      break;
    if (condStr.nExpireInHoliday == 1 && info.IsExpireInHoliday())  // 不含假期
      break;
    passed = true;
  } while (0);
  return passed;
}

bool CSSVContainer::IsCFETSBondPassCondition(int nIndex,
                                             const BLHCONDITION& condStr,
                                             bool bSecondaryMarket) {
  // by scofined.qi ,将bool CSSVContainer::Retrieve( BLHCONDITION & condStr,
  // std::vector<int> & array_result, bool bSecondaryMarket)
  // 里的逻辑抽取出来作为静态函数,可提供给外部使用;
  CBondContainer& gc = CBondContainer::instance();
  if (!gc.IsValidIndex(nIndex)) return false;
  const CBondInfo& info = gc.ElementAtR(nIndex);
  bool passed = false;
  do {
    if (info.IsExchange())  // 交易所债券不显示
      break;
    if (info.IsAddIssueBond()) break;  // 增续发
    if (condStr.nHasFlg != 0 &&
        !gc.IsCFETSHasPrice(condStr, nIndex))  // 有效报价
      break;
    if (condStr.nBothFlg != 0 &&
        !gc.IsCFETSBilateralPrice(condStr, nIndex))  // 双边报价
      break;
    if (condStr.nSettlement[0] != CBondContainer::StmAll &&
        !gc.CheckCFETSSettlement(condStr, nIndex))  // 清算速度
      break;
    if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
      break;
    if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
      break;
    if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
      break;
    if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
      break;
    if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
      break;
    if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
      break;
    if (!IsEmpty(condStr.sDiffPrice) &&
        !gc.GetCFETSDiffPrice(condStr, nIndex))  // BP差
      break;
    if ((strlen(condStr.sBPrice) != 0 || strlen(condStr.sBPriceEnd) != 0) &&
        !gc.GetCFETSBidCndPrice(condStr, nIndex))  // bid
      break;
    if ((strlen(condStr.sOPrice) != 0 || strlen(condStr.sOPriceEnd) != 0) &&
        !gc.GetCFETSOfrCndPrice(condStr, nIndex))  // ofr
      break;
    if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
        !info.CheckCommonUseType(condStr))  // 常用
      break;
    if (condStr.nType[0] != CBondContainer::BondAll &&
        !info.CheckBondType(condStr))  // 产品
      break;
    if (condStr.nGSMType[0] != CBondContainer::BondC_All &&
        !info.CheckGSMBondType(condStr))  // 公募私募产品类型
      break;
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
        !gc.GetMultiLevel(condStr, info))  // 主体评级
      break;

    if (condStr.nOutlookRating[0] != CBondContainer::OutlookRatingAll &&
        !gc.GetOutlookRatingLevel(condStr, info))
      break;

    if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll &&
        !gc.GetCDCRatingLevel(condStr, info))  // 中债隐含
      break;
    if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll &&
        !gc.GetCSIRatingLevel(condStr, info))  // 中证隐含
      break;
    if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll &&
        !gc.GetCBRRatingLevel(condStr, info))  // 中债资信
      break;

    if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
        !gc.GetWarrType(condStr, info))  // 有担保
      break;
    if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
        !gc.GetMultiCouponType(condStr, info))  // 特殊分类
      break;
    if (condStr.nRight != CBondContainer::RightAll &&
        gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
      break;
    if (condStr.nRightEx[0] != CBondContainer::RightExAll &&
        !info.CheckRightEx(condStr))  // 含权类型
      break;
    if (condStr.nRange[0] != CBondContainer::RangeAll &&
        !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
      break;
    if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
        !gc.GetMunicpType(condStr, info))  // 城投
      break;
    if (condStr.nInstion[0] != CBondContainer::InstAll &&
        !gc.GetMultiInstion(condStr, info))  // 机构类型
      break;
    if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr))  // 发行人
      break;
    if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
      break;
    if (condStr.szSector2021[0][0] != '\0' &&
        !info.CheckSector2021(condStr))  // 行业
      break;
    if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
      break;
    if (condStr.szSubType[0][0] != '\0' &&
        !info.CheckBontSubType(condStr))  // 细分
      break;
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
        !info.CheckDebtRating(condStr))  // 债项评级
      break;
    if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
        !info.CheckFinDebt(condStr))  // 金融债
      break;
    if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
        !gc.IsPlatformType(condStr, info))  //
      break;
    if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
        !gc.IsLocalBond(condStr, info))  //
      break;
    //  add  by  lbl  NCD
    if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
        !info.CheckNCDRating(condStr))  // NCD
      break;
    if (condStr.nIssueYear[0] != 0 &&
        !info.CheckIssueYear(condStr))  // 发行年份
      break;
    if (condStr.nCreditBond != 0 &&
        !info.IsCreditBond(condStr))  // 信用债,利率债
      break;
    // if (strlen(condStr.sVolBid) != 0 && !gc.GetVolBidCompare(condStr,
    // nIndex)) //vol.bid 	break; if (strlen(condStr.sVolOfr) != 0 &&
    // !gc.GetVolOfrCompare(condStr, nIndex)) //vol.ofr 	break;
    if (condStr.nETSBond[0] != CBondContainer::ETSBondAll &&
        !gc.IsETSBondType(condStr, info))  // 永续债
      break;
    // if (condStr.nCorpBond[0] != CBondContainer::CorpBondAll &&
    // !gc.IsCorpBondType(condStr, info))	 //公司债 	break; CFETS
    // 没有公司债
    if (condStr.nAssetStatus[0] != CBondContainer::AssetAll &&
        !info.CheckAssetStatus(condStr))  // 发行
      break;
    if (!IsEmpty(condStr.sBidCdc) &&
        !gc.GetCFETSBidCdcCompare(condStr, nIndex,
                                  info.IsCDCAuthValid()))  // bid-中债
      break;
    if (!IsEmpty(condStr.sCdcOfr) &&
        !gc.GetCFETSCdcOfrCompare(condStr, nIndex,
                                  info.IsCDCAuthValid()))  // 中债-ofr
      break;
    if (!IsEmpty(condStr.sVolBid) &&
        !gc.GetCFETSBidVol(condStr, nIndex))  // bid.vol
      break;
    if (!IsEmpty(condStr.sVolOfr) &&
        !gc.GetCFETSOfrVol(condStr, nIndex))  // ofr.vol
      break;
    if (condStr.nExpireInHoliday == 1 && info.IsExpireInHoliday())  // 不含假期
      break;
    passed = true;
  } while (0);
  return passed;
}

bool CSSVContainer::IsCFETSDealPassCondition(int nIndex,
                                             const BLHCONDITION& condStr) {
  CBondContainer& gc = CBondContainer::instance();
  if (!gc.IsValidIndex(nIndex)) return false;
  const CBondInfo& info = gc.ElementAtR(nIndex);
  bool passed = false;
  do {
    if (info.IsExchange())  // 交易所债券不显示
      break;
    if (info.IsAddIssueBond()) break;               // 增续发
    if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
      break;
    if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
      break;
    if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
      break;
    if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
      break;
    if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
      break;
    if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
      break;
    if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
        !info.CheckCommonUseType(condStr))  // 常用
      break;
    if (condStr.nType[0] != CBondContainer::BondAll &&
        !info.CheckBondType(condStr))  // 产品
      break;
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
        !gc.GetMultiLevel(condStr, info))  // 主体评级
      break;

    if (condStr.nOutlookRating[0] != CBondContainer::OutlookRatingAll &&
        !gc.GetOutlookRatingLevel(condStr, info))
      break;

    if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll &&
        !gc.GetCDCRatingLevel(condStr, info))  // 中债隐含
      break;
    if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll &&
        !gc.GetCSIRatingLevel(condStr, info))  // 中证隐含
      break;
    if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll &&
        !gc.GetCBRRatingLevel(condStr, info))  // 中债资信
      break;
    if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
        !gc.GetWarrType(condStr, info))  // 有担保
      break;
    if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
        !gc.GetMultiCouponType(condStr, info))  // 特殊分类
      break;
    if (condStr.nRight != CBondContainer::RightAll &&
        gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
      break;
    if (condStr.nRightEx[0] != CBondContainer::RightExAll &&
        !info.CheckRightEx(condStr))  // 含权类型
      break;
    if (condStr.nRange[0] != CBondContainer::RangeAll &&
        !gc.GetMaturityRange(condStr, info, true))  // 剩余期限
      break;
    if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
        !gc.GetMunicpType(condStr, info))  // 城投
      break;
    if (condStr.nInstion[0] != CBondContainer::InstAll &&
        !gc.GetMultiInstion(condStr, info))  // 机构类型
      break;
    if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr))  // 发行人
      break;
    if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
      break;
    if (condStr.szSector2021[0][0] != '\0' &&
        !info.CheckSector2021(condStr))  // 行业
      break;
    if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
      break;
    if (condStr.szSubType[0][0] != '\0' &&
        !info.CheckBontSubType(condStr))  // 细分
      break;
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
        !info.CheckDebtRating(condStr))  // 债项评级
      break;
    if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
        !info.CheckFinDebt(condStr))  // 金融债
      break;
    if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
        !gc.IsPlatformType(condStr, info))  // 平台债
      break;
    if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
        !gc.IsLocalBond(condStr, info))  // 地方债
      break;
    //  add  by  lbl  NCD
    if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
        !info.CheckNCDRating(condStr))  // NCD
      break;
    if (condStr.nAssetStatus[0] != CBondContainer::AssetAll &&
        !info.CheckAssetStatus(condStr))  // 发行
      break;
    if (condStr.nIssueYear[0] != 0 &&
        !info.CheckIssueYear(condStr))  // 发行年份
      break;
    if (condStr.nCreditBond != 0 &&
        !info.IsCreditBond(condStr))  // 信用债,利率债
      break;
    if (condStr.nETSBond[0] != CBondContainer::ETSBondAll &&
        !gc.IsETSBondType(condStr, info))  // 永续债
      break;
    if (condStr.nExpireInHoliday == 1 && info.IsExpireInHoliday())  // 不含假期
      break;
    passed = true;
  } while (0);
  return passed;
}

bool CSSVContainer::IsABSBondPassCondition(int nIndex,
                                           const BLHCONDITION& condStr,
                                           bool bSecondaryMarket) {
  // by scofined.qi ,将bool CSSVContainer::Retrieve( BLHCONDITION & condStr,
  // std::vector<int> & array_result, bool bSecondaryMarket)
  // 里的逻辑抽取出来作为静态函数,可提供给外部使用;
  //
  // 删除报价相关筛选，edit by Lance，2021.8.20
  CBondContainer& gc = CBondContainer::instance();
  if (!gc.IsValidIndex(nIndex)) return false;

  const CABSBondInfo* absinfo = gc.GetABSBondInfo(nIndex);
  const CBondInfo& info = gc.ElementAtR(nIndex);
  if (!info.IsBondABS() || info.IsExchange()) return false;
  bool passed = false;
  do {
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
        !gc.GetMultiLevel(condStr, info))  // 主体评级
      break;
    if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll &&
        !gc.GetCDCRatingLevel(condStr, info))  // 中债隐含
      break;
    if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll &&
        !gc.GetCSIRatingLevel(condStr, info))  // 中证隐含
      break;
    if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll &&
        !gc.GetCBRRatingLevel(condStr, info))  // 中债资信
      break;
    if (condStr.nRange[0] != CBondContainer::RangeAll &&
        !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
      break;
    if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
        !gc.GetMunicpType(condStr, info))  // 城投
      break;
    if (condStr.nInstion[0] != CBondContainer::InstAll &&
        !gc.GetMultiInstion(condStr, info))  // 企业
      break;
    if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr))  // 发起人
      break;
    if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
      break;
    if (condStr.szSector2021[0][0] != '\0' &&
        !info.CheckSector2021(condStr))  // 行业
      break;
    if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
      break;
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
        !info.CheckDebtRating(condStr))  // 债项评级
      break;
    if (condStr.nIssueYear[0] != 0 &&
        !info.CheckIssueYear(condStr))  // 发行年份
      break;
    if (condStr.nABSCommonUse[0] != CABSBondInfo::COMMON_ALL &&
        (!absinfo || !absinfo->CheckCommon(condStr)))  // ABS常用
      break;
    if ((condStr.nABSIssueBegin > 0 || condStr.nABSIssueEnd > 0) &&
        !info.CheckIssueYear(condStr.nABSIssueBegin,
                             condStr.nABSIssueEnd))  // ABS发行年份
      break;
    if (condStr.nABSBaseType[0] != CABSBondInfo::BASETYPE_ALL) {
      bool hasOther = false;
      for (int i = 0; i < 20; i++) {
        if (condStr.nABSBaseType[i] == CABSBondInfo::BASETYPE_OTHER) {
          hasOther = true;
          break;
        }
        if (condStr.nABSBaseType[i] == 0) break;
      }

      if (!absinfo && !hasOther)
        break;
      else if (absinfo && !absinfo->CheckBaseType(condStr))
        break;
    }
    if (condStr.nABSTrancheClass[0] != CABSBondInfo::TRANCHECLASS_ALL &&
        (!absinfo || !absinfo->CheckTrancheClass(condStr)))  // ABS产品结构
      break;
    if (condStr.nABSCoupon[0] != CABSBondInfo::COUPON_ALL &&
        !info.CheckABSCoupon(condStr))  // ABS票面
      break;
    if (condStr.szABSSeries[0][0] != '\0' &&
        (!absinfo || !absinfo->CheckSeries(condStr)))  // ABS系列
      break;
    if (condStr.szABSIssuer[0][0] != '\0' &&
        (!absinfo || !absinfo->CheckIssuer(condStr)))  // ABS发行人
      break;
    if (condStr.szMainUnderwriter[0][0] != '\0' &&
        !info.CheckMainUnderwriter(condStr))  // 主承机构
      break;
    // 		if (condStr.nExpireInHoliday == 1 &&
    // info.IsExpireInHoliday())//不含假期 			break;
    passed = true;
  } while (0);
  return passed;
}

bool CSSVContainer::ExtractFrom(const std::vector<int>& source,
                                std::vector<int>& dest,
                                const BLHCONDITION& condStr,
                                bool bSecondaryMarket) {
  CBondContainer& gc = CBondContainer::instance();

  if (condStr.nBrokId[0] == 0 && strlen(condStr.sCompanyid) == 0) return false;

  if (condStr.m_bFilterConditon && condStr.isEmptyCondition())
    return true;  // 我的方案如果为空，则数据为0 add by givins.zhu 2020 0806
  if (condStr.isAllin()) {
    for (auto it = source.begin(); it != source.end(); it++)
      dest.push_back(*it);

    return true;
  }

  Extract(source, dest, condStr, bSecondaryMarket);
  return true;
}

bool CSSVContainer::ExtractWithSearchString(std::vector<int>& dest,
                                            BLHCONDITION& condStr, int nType,
                                            const char* sSearch,
                                            bool bSecondaryMarket) {
  std::lock_guard<std::mutex> locker(m_mutex);
  dest.clear();
  if (nType == 1 && !IsEmpty(sSearch)) {  // 精确定位，不考虑筛选条件
    CBondContainer& gc = CBondContainer::instance();
    int bondIndex = gc.GetBondIndex(sSearch);
    if (!gc.IsValidIndex(bondIndex)) return false;

    if (std::find(m_array_result.begin(), m_array_result.end(), bondIndex) ==
        m_array_result.end())
      return false;
    dest.push_back(bondIndex);
    return true;
  }

  if (nType == 0 && !IsEmpty(sSearch)) {
    IntArray vctTemp;
    ExtractFrom(m_array_result, vctTemp, condStr, bSecondaryMarket);
    CBondContainer& gc = CBondContainer::instance();
    for (auto it : vctTemp) {
      const CBondInfo& info = gc.ElementAtR(it);
      if (info.IsAddIssueBond()) continue;  // 增续发跳过
      if (info.IsExpireBond()) continue;    // 过期券跳过
      CSPString strBondID = info.GetCombBondCode();
      strBondID = strBondID.substr(0, strlen(sSearch));
      if (strBondID.compare(sSearch) == 0 ||
          strstr(info.GetBondShortName(), sSearch) ||
          info.MatchJianpin(sSearch)) {
        dest.push_back(it);
      }
    }
    return true;
  } else {
    return ExtractFrom(m_array_result, dest, condStr, bSecondaryMarket);
  }
  return true;
}

bool CSSVContainer::Retrieve(BLHCONDITION& condStr,
                             std::vector<int>& array_result,
                             bool bSecondaryMarket) {
  std::lock_guard<std::mutex> locker(m_mutex);
  return ExtractFrom(m_array_result, array_result, condStr, bSecondaryMarket);
}

bool CSSVContainer::Retrieve(BLHCONDITION& condStr, char* FilterBondKey,
                             std::vector<int>& array_result,
                             bool bSecondaryMarket) {
  std::lock_guard<std::mutex> locker(m_mutex);

  m_lcond = condStr;
  CBondContainer& gc = CBondContainer::instance();

  if (condStr.nBrokId[0] == 0 && strlen(condStr.sCompanyid) == 0) return false;

  std::vector<int>::iterator it;
  if (condStr.isAllin()) {
    for (it = m_array_result.begin(); it != m_array_result.end(); it++)
      array_result.push_back(*it);
    return true;
  }

  for (int n = 0; n < GetSize(); n++) {
    int nIndex = m_array_result[n];
    if (!gc.IsValidIndex(nIndex)) continue;
    const CBondInfo& info = gc.ElementAtR(nIndex);
    if (FilterBondKey != nullptr &&
        strcmp(info.GetCombBondKey(), FilterBondKey) == 0)
      continue;

    bool bContinue = false;
    do {
      if (condStr.nValid != 0 && !gc.IsBCQuoteValid(condStr, nIndex)) break;
      if (condStr.nBothFlg != 0 && !gc.IsBilateralPrice(condStr, nIndex)) break;
      if (condStr.nNewFlg != 0 && !info.IsNewBond()) break;
      if (condStr.nHasFlg != 0 && !gc.IsHasPrice(condStr, nIndex)) break;
      if (condStr.nMatFlg != 0 && info.IsExpireBond()) break;
      if (condStr.nASemi != 0 && !info.IsRebated()) break;
      if (condStr.nMortgt != 0 && !info.IsMortgage()) break;
      if (condStr.nCrosmk != 0 && !info.IsCrossMarket()) break;
      if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info)) break;
      if (condStr.nOffset != 0 && !gc.GetBondOffsetEstPrc(condStr, nIndex))
        break;
      if (!IsEmpty(condStr.sDiffPrice) && !gc.GetDiffPrice(condStr, nIndex))
        break;
      if ((strlen(condStr.sBPrice) != 0 || strlen(condStr.sBPriceEnd) != 0) &&
          !gc.GetBidCndPrice(condStr, nIndex))
        break;
      if ((strlen(condStr.sOPrice) != 0 || strlen(condStr.sOPriceEnd) != 0) &&
          !gc.GetOfrCndPrice(condStr, nIndex))
        break;
      if (condStr.nType[0] != CBondContainer::BondAll &&
          !info.CheckBondType(condStr))
        break;
      if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
          !gc.GetMultiLevel(condStr, info))
        break;
      if (condStr.nOutlookRating[0] != CBondContainer::OutlookRatingAll &&
          !gc.GetOutlookRatingLevel(condStr, info))
        break;
      if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll &&
          !gc.GetCDCRatingLevel(condStr, info))
        break;
      if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll &&
          !gc.GetCSIRatingLevel(condStr, info))
        break;
      if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll &&
          !gc.GetCBRRatingLevel(condStr, info))
        break;
      if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
          !gc.GetWarrType(condStr, info))
        break;
      if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
          !gc.GetMultiCouponType(condStr, info))
        break;
      if (condStr.nRight != CBondContainer::RightAll &&
          gc.GetRightType(condStr.nRight) != info.IsRight())
        break;
      if (condStr.nRange[0] != CBondContainer::RangeAll &&
          !gc.GetMaturityRange(condStr, info, bSecondaryMarket))
        break;
      if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
          !gc.GetMunicpType(condStr, info))
        break;
      if (condStr.nInterbank != 0 && !info.IsInterbank()) break;
      if (condStr.nExchange != 0 && !info.IsExchange()) break;
      if (condStr.nInstion[0] != CBondContainer::InstAll &&
          !gc.GetMultiInstion(condStr, info))
        break;
      if (condStr.szIssuer[0][0] != '\0' && !info.CheckIssuer(condStr)) break;
      if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr)) break;
      if (condStr.szSector2021[0][0] != '\0' && !info.CheckSector2021(condStr))
        break;
      if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr)) break;
      if (condStr.szSubType[0][0] != '\0' && !info.CheckBontSubType(condStr))
        break;
      if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
          !info.CheckDebtRating(condStr))
        break;
      if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
          !info.CheckFinDebt(condStr))
        break;
      if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
          !gc.IsPlatformType(condStr, info))  // 平台债
        break;
      if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
          !gc.IsLocalBond(condStr, info))  // 地方债
        break;
      //  add  by  lbl  NCD
      if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
          !info.CheckNCDRating(condStr))  // NCD
        break;
      // end
      if (condStr.nIssueYear[0] != 0 && !info.CheckIssueYear(condStr)) break;
      if (condStr.nStateType != 0 && !gc.GetStateType(condStr, info)) break;
      // if(condStr.nUnderwriter != 0 && info.m_sIsUnderwriter!='1')
      //	break;
      if (strlen(condStr.szIssueDateB) != 0 &&
          strlen(condStr.szIssueDateE) != 0 &&
          !gc.GetIssueStartDate(condStr, info))
        break;
      if (condStr.szUnderwriter[0] != 0 && !info.CheckUnderwriter(condStr))
        break;
      if (condStr.nCreditBond != 0 && !info.IsCreditBond(condStr)) break;
      if (!info.IsInDays(condStr)) break;
      if (condStr.nExpireInHoliday == 1 &&
          info.IsExpireInHoliday())  // 不含假期
        break;
      bContinue = true;
    } while (0);
    if (bContinue) array_result.push_back(nIndex);
  }
  return true;
}

bool CSSVContainer::RetrieveFromStatic(int nFilterType, const char* szType,
                                       std::vector<int>& array_result) {
  std::lock_guard<std::mutex> locker(m_mutex);
  array_result.clear();

  if (nFilterType == CBondContainer::typeNone) return true;

  if (nFilterType < CBondContainer::typeMin ||
      nFilterType > CBondContainer::typeMax)
    return false;

  if (nFilterType == CBondContainer::typeBondType ||
      nFilterType == CBondContainer::typeOption) {
    if (nullptr == szType || strlen(szType) <= 0)
      nFilterType = CBondContainer::typeAll;
  }

  std::vector<int>::iterator it;
  CBondContainer& gc = CBondContainer::instance();
  switch (nFilterType) {
    case CBondContainer::typeBondType: {
      const char* szbondsubtype;
      for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
        const CBondInfo& info = gc.ElementAtR(*it);
        if (info.IsAddIssueBond()) {
          continue;
        }
        szbondsubtype = info.GetBondSubType();
        if (szType && strcmp(szType, szbondsubtype) == 0) {
          array_result.push_back(*it);
        }
      }
    } break;
    case CBondContainer::typeExternal:
    case CBondContainer::typeAttribute:
    case CBondContainer::typeCoupon:
    case CBondContainer::typeOption:
    case CBondContainer::typeArgument:
    case CBondContainer::typeDate:
    case CBondContainer::typeRating:
      break;
    case CBondContainer::typeBondID: {
      for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
        const CBondInfo& info = gc.ElementAtR(*it);
        if (info.IsAddIssueBond()) {
          continue;
        }

        if (info.IsExpireBond()) continue;
        CSPString strBondID = info.GetCombBondCode();
        strBondID = strBondID.substr(strlen(szType));
        if (strcmp(strBondID.c_str(), szType) == 0 ||
            strstr(info.GetBondShortName(), szType) ||
            info.MatchJianpin(szType)) {
          array_result.push_back(*it);
        }
      }
    } break;
    case CBondContainer::typeBondKey: {
      int bondIndex = gc.GetBondIndex(szType);
      if (!gc.IsValidIndex(bondIndex)) break;
      std::vector<int>::iterator it =
          std::find(m_array_result.begin(), m_array_result.end(), bondIndex);
      if (it != m_array_result.end()) {
        const CBondInfo& info = gc.ElementAtR(bondIndex);
        if (!info.IsAddIssueBond() && !info.IsExpireBond())
          array_result.push_back(bondIndex);
      }
    } break;
    case CBondContainer::typeBondExpiry: {
      for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
        const CBondInfo& info = gc.ElementAtR(*it);
        if (info.IsAddIssueBond()) {
          continue;
        }
        if (!info.IsExpireBond()) {
          array_result.push_back(*it);
        }
      }
    } break;
    case CBondContainer::typeMarketType: {
      for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
        const CBondInfo& info = gc.ElementAtR(*it);
        if (info.IsAddIssueBond()) {
          continue;
        }
#ifdef WIN32
        if (qstricmp(info.GetMarketType(), szType) == 0) {
#else
        if (strcasecmp(info.GetMarketType(), szType) == 0) {
#endif
          array_result.push_back(*it);
        }
      }
    }
    default:
      return false;
  }

  return true;
}

bool CSSVContainer::GetCompanyRepByKey(const char* szBondKey, const char* szKey,
                                       REPORT& stRep) {
  return CBondContainer::instance().GetCompanyRepByKey(szBondKey, szKey, stRep);
}

bool CSSVContainer::GetCompanyRepById(int nId, const char* szKey,
                                      REPORT& stRep) {
  if (nId < 0 || nId >= GetSize()) return false;
  return CBondContainer::instance().GetCompanyRepById(m_array_result[nId],
                                                      szKey, stRep);
}

bool CSSVContainer::GetClentQuotByKey(const char* szBondKey, const char* szKey,
                                      BKQUOTE& stQuot) {
  return CBondContainer::instance().GetClentQuotByKey(szBondKey, szKey, stQuot);
}

bool CSSVContainer::GetCompanyRepByKey(const char* szBondKey, REPORT& stRep) {
  return CBondContainer::instance().GetCompanyRepByKey(szBondKey, stRep);
}

CBondCompanyRep* CSSVContainer::GetCompanyRep(const BrokerKey& szID) {
  return CBondContainer::instance().GetCompanyRep(szID.m_nIndex);
}

bool CSSVContainer::SetContent(const std::list<std::string>& m_brokls) {
  m_bDataChanged = true;
  m_brokevec.m_vct.clear();
  m_brokevec.m_vct.reserve(m_array_result.size() * m_brokls.size());
  for (auto nTmpKey : m_array_result) {
    if (nTmpKey < 0 || nTmpKey >= GetAllBondsSize()) continue;
    for (const auto& broker : m_brokls)
      m_brokevec.m_vct.emplace_back(BrokerKey(broker, nTmpKey));
  }
  return true;
}

bool CSSVContainer::SetContent(const std::string& sCompanyId) {
  const int idsize = (sizeof(((report_t*)0)->m_company_id));
  char company_id[idsize] = {0};

  m_brokevec.m_vct.clear();
  m_brokevec.m_vct.reserve(m_brokevec.m_vct.size() + m_array_result.size());
  CBondContainer& bc = CBondContainer::instance();
  if (sCompanyId.empty())  ////为空时，取所有报价中时间最新的报价broker
  {
    for (auto bondIndex : m_array_result) {
      ////为空时，取所有报价中时间最新的报价broker
      bool usenew = bc.GetCompanyIdFromRep(bondIndex, "", company_id, idsize);
      m_brokevec.m_vct.emplace_back(
          BrokerKey(usenew ? company_id : sCompanyId.c_str(), bondIndex));
    }
  } else {
    for (auto bondIndex : m_array_result)
      m_brokevec.m_vct.emplace_back(BrokerKey(sCompanyId, bondIndex));
  }
  return true;
}

void CSSVContainer::AddBrokerVector(const BrokerKey& brokerkey) {
  for (const auto& itor : m_brokevec.m_vct) {
    if (brokerkey.GetBrokerId() == itor.GetBrokerId() &&
        brokerkey.m_nIndex == itor.m_nIndex)
      return;
  }

  m_brokevec.m_vct.push_back(brokerkey);
  m_bDataChanged = true;
}

REPORT* CSSVContainer::GetCompanyInfoById(const std::string& szKey,
                                          const BrokerKey& szID) {
  std::lock_guard<std::mutex> locker(m_mutex);

  static REPORT stRep;
  memset(&stRep, 0, sizeof(stRep));
  CBondCompanyRep* ptmp = GetCompanyRep(szID);
  if (ptmp) {
    ptmp->GetCompanyRepByKey(szKey, stRep);
  }
  return &stRep;
}

bool CSSVContainer::IsPriceNeedShow(const BLHCONDITION& Cond,
                                    const REPORT& report, int nKey,
                                    bool checkValidPrice) {
  // 总共有5项检查,只有全部通过,才能显示在界面的表格中
  // 返回true表示需要显示在界面中,false表示不显示在界面中
  // 检查报价是否是有效报价,只有当有效报价勾选后,才会去检查
  // 2021/09/16新增清算速度筛选
  if (checkValidPrice && CheckBestPrice(Cond, report, nKey)) return false;

  REPORT rpt;
  RebuildReportBySettlement(Cond, report, rpt);

  // 清算速度
  if (!CheckSettlementLite(Cond, rpt)) return false;

  // 检查是否是双边报价,已经包含检查双边后面的edit内容
  if (!CheckBilateralBestPrice(Cond, rpt, nKey)) return false;

  if (!CheckDiffPrice(Cond, rpt)) return false;

  // 价差报价的bid/ofr后的edit筛选,预先检测Bid/Ofr后面的Edit内容是否有一个有值
  if (!CheckPriceValuate(Cond, rpt, nKey)) return false;

  // 检查|bid-中债|,预先检测其后的edit内容是否不为空
  if (!CheckBidCdcPriceValuate(Cond, rpt, nKey)) return false;

  // 检查|中债-ofr|,预先检测其后的edit内容是否不为空
  if (!CheckCdcOfrPriceValuate(Cond, rpt, nKey)) return false;

  // 检查bid.vol,预先检测其后的edit内容是否不为空
  if (!CheckBidVol(Cond, rpt)) return false;

  // 检查ofr.vol,预先检测其后的edit内容是否不为空
  if (!CheckOfrVol(Cond, rpt)) return false;

  return true;
}

bool CSSVContainer::CheckBestPrice(const BLHCONDITION& Cond,
                                   const REPORT& report, int nKey) {
  // true -- 无效报价， false -- 有效报价
  // 条件1：双边 m_price_status = 空，或= 0，判定无效
  // 条件2：双边 m_bp_status != 0，判定无效
  // 条件3：双边 m_sPrice = 空，判定无效

  if (Cond.nHasFlg == 0) return false;
  if (Cond.nBnkFlg != 2) {
    if (strcmp(report.m_bidinfo.m_bp_status, "0") != 0 &&
        strcmp(report.m_askinfo.m_bp_status, "0") != 0)
      return true;
    if ((strcmp(report.m_bidinfo.m_price_status, "0") == 0 ||
         strcmp(report.m_bidinfo.m_price_status, "") == 0) &&
        (strcmp(report.m_askinfo.m_price_status, "0") == 0 ||
         strcmp(report.m_askinfo.m_price_status, "") == 0))
      return true;

    if (IsEmpty(report.m_bidinfo.m_sPrice) &&
        IsEmpty(report.m_askinfo.m_sPrice))
      return true;

    return false;
  } else {
    if (IsEmpty(report.m_indx_info.m_price)) return true;
  }
  return false;
}

bool CSSVContainer::CheckBilateralBestPrice(const BLHCONDITION& Cond,
                                            const REPORT& report, int nKey) {
  // true:表示通过检测,满足双边价格检查,false:表示没有通过检测,不出现在最终结果集合中
  // 双边未勾选,忽略,通过检测
  // 此函数只判断双边,不判断双边之后edit内容的过滤
  if (Cond.nBothFlg != 1) return true;

  if (Cond.nBnkFlg != 2) {
    // 放在前面更容易通过,更快:只要有一个价格为无效价格,那么不通过
    if (IsNullPrice(report.m_bidinfo.m_sPrice) ||
        IsNullPrice(report.m_askinfo.m_sPrice))
      return false;

    if (strcmp(report.m_bidinfo.m_price_status, "0") == 0 ||
        strcmp(report.m_askinfo.m_price_status, "0") == 0 ||
        strcmp(report.m_bidinfo.m_price_status, "") == 0 ||
        strcmp(report.m_askinfo.m_price_status, "") == 0)
      return false;

    return true;
  }
  return IsEmpty(report.m_indx_info.m_price) ? false : true;
}

bool CSSVContainer::CheckPriceValuate(const BLHCONDITION& Cond,
                                      const REPORT& report, int nKey) {
  // 检查债券是否符合Bid,Ofr两个筛选条件
  // true:表示通过检测,false:表示没有通过检测,不出现在最终结果集合中
  // 当edit内容过小的时候,忽略检测,直接通过
  // 没有开关标志,检测对应的edit内容是否为空,为空,则直接返回true;
  return CheckReportPrice(report.m_askinfo, Cond.sOPrice, Cond.sOPriceEnd,
                          Cond.nOpcCnd) &&
         CheckReportPrice(report.m_bidinfo, Cond.sBPrice, Cond.sBPriceEnd,
                          Cond.nBpcCnd);
}

bool CSSVContainer::CheckBidCdcPriceValuate(const BLHCONDITION& Cond,
                                            const REPORT& report, int nKey) {
  // 检查|bid-中债|,预先检测其后的edit内容是否不为空
  // true:表示通过检测,false:表示没有通过检测,不出现在最终结果集合中
  if (IsEmpty(Cond.sBidCdc)) return true;
  const CBondInfo& info = CBondContainer::instance().ElementAtR(nKey);
  bool bIsCDCAuthValid = info.IsCDCAuthValid();
  if (!bIsCDCAuthValid) return false;
  if (IsReportPriceHasNumber(report.m_bidinfo))  // 有效价格
  {
    double dBidPrice = atof(report.m_bidinfo.m_yield_price);
    if (atoi(report.m_bidinfo.m_quotetype) != 3 &&
        (info.IsBondABS() || info.IsTransBond())) {
      if (dBidPrice <= 0 || dBidPrice >= 30) return false;
    }
    double dDiff = CBondCDCPriceInfo::instance().GetEstimatePriceGap(
        bIsCDCAuthValid, nKey, CBondCDCPriceInfo::price_type_yield, true,
        report.m_bidinfo.m_yield_price);
    if (dDiff <= INVALID_CDC_VALUE) return false;
    if (CheckBpPriceByOp(Cond.sBidCdc, Cond.sBidCdcEnd, dDiff)) return true;
  }

  return false;
}

bool CSSVContainer::CheckCdcOfrPriceValuate(const BLHCONDITION& Cond,
                                            const REPORT& report, int nKey) {
  if (IsEmpty(Cond.sCdcOfr)) return true;
  const CBondInfo& info = CBondContainer::instance().ElementAtR(nKey);
  bool bIsCDCAuthValid = info.IsCDCAuthValid();
  if (!bIsCDCAuthValid) return false;
  if (IsReportPriceHasNumber(report.m_askinfo))  // 有效价格
  {
    double dOfrPrice = atof(report.m_askinfo.m_yield_price);
    if (atoi(report.m_askinfo.m_quotetype) != 3 &&
        (info.IsBondABS() || info.IsTransBond())) {
      if (dOfrPrice <= 0 || dOfrPrice >= 30) return false;
    }
    double dDiff = CBondCDCPriceInfo::instance().GetEstimatePriceGap(
        bIsCDCAuthValid, nKey, CBondCDCPriceInfo::price_type_yield, false,
        report.m_askinfo.m_yield_price);
    if (dDiff <= INVALID_CDC_VALUE) return false;
    if (CheckBpPriceByOp(Cond.sCdcOfr, Cond.sCdcOfrEnd, dDiff)) return true;
  }

  return false;
}

bool CSSVContainer::DelBrokerVector(const BrokerKey& brokerkey) {
  auto itor = m_brokevec.m_vct.begin();
  for (; itor != m_brokevec.m_vct.end(); itor++) {
    if (brokerkey.GetBrokerId() == itor->GetBrokerId() &&
        brokerkey.m_nIndex == itor->m_nIndex) {
      m_brokevec.m_vct.erase(itor);
      m_bDataChanged = true;
      return true;
    }
  }
  return false;
}

REPORT* CSSVContainer::GetCompanyInfoById(const std::string& szKey, int nID) {
  std::lock_guard<std::mutex> locker(m_mutex);

  if (nID < 0 || nID >= GetSize()) return nullptr;

  static REPORT stRep;
  memset(&stRep, 0, sizeof(stRep));
  CBondCompanyRep* ptmp = GetCompanyRep(nID);
  if (ptmp) {
    ptmp->GetCompanyRepByKey(szKey, stRep);
  }
  return &stRep;
}

REPORT* CSSVContainer::GetCompanyInfoById(int nID) {
  std::lock_guard<std::mutex> locker(m_mutex);

  if (nID < 0 || nID >= GetSize()) return nullptr;

  static REPORT stRep;
  memset(&stRep, 0, sizeof(stRep));
  CBondCompanyRep* ptmp = GetCompanyRep(nID);
  if (ptmp && ptmp->GetSize() > 0) {
    GetCompanyRepById(nID, stRep);
  }
  return &stRep;
}

int CSSVContainer::ElementAt(int nIndex) {
  if (nIndex >= 0 && nIndex < (int)m_array_result.size()) {
    return m_array_result[nIndex];
  }
  return -1;
}

const CBondInfo& CSSVContainer::ElementAt2(int nIndex) const {
  if (nIndex < 0 || nIndex >= (int)m_array_result.size()) {
    static CBondInfo m_infoNull;
    return m_infoNull;
  }
  // SP_ASSERT(nIndex >= 0 && nIndex < (int)m_array_result.size());
  return CBondContainer::instance().ElementAtR(m_array_result[nIndex]);
}

CBondCompanyRep* CSSVContainer::GetCompanyRep(int nIndex) {
  return CBondContainer::instance().GetCompanyRep(m_array_result[nIndex]);
}

bool CSSVContainer::GetCompanyRepById(int nIndex, REPORT& stRep) {
  return CBondContainer::instance().GetCompanyRepById(m_array_result[nIndex],
                                                      stRep);
}

CBondBankRep* CSSVContainer::GetBankRep(int nIndex) {  // 获取银行报价对象
  return CBondContainer::instance().GetBankRep(m_array_result[nIndex]);
}

CBondBankRep* CSSVContainer::GetClntRep(int nIndex) {
  return CBondContainer::instance().GetClntRep(m_array_result[nIndex]);
}

void CSSVContainer::SetBondParam(int sort_key, const std::string& szKey,
                                 bool bDesc) {
  m_bDesc = bDesc;
  m_sort_key = sort_key;
  m_szKey = szKey;
}

// void CSSVContainer::SetServerTime(time_t servertime)
// {
// 	CBondContainer::instance().SetServerTime(servertime);
// }

time_t CSSVContainer::GetServerTime() {
  return ServerTimeMgr::instance().serverTime();
}

inline bool CSSVContainer::GetTopCompare(const int& i, const int& j,
                                         const bool& bDesc, int sort_key) {
  if (bDesc)
    return i < j;
  else
    return j < i;
}

int CSSVContainer::GetTopCompareEx(const int& i, const int& j,
                                   const bool& bDesc /*=false*/,
                                   int sort_key /*= VMODIFY_TIME*/) {
  if (bDesc)
    return i - j;
  else
    return j - i;
}

inline double CSSVContainer::GetTakenPriceByKey(const char* pszKey,
                                                const char* pszMarket,
                                                void* pList,
                                                const std::string& brokerid) {
  MarketStreamPriceMap* psmap = (MarketStreamPriceMap*)pList;
  double dfreturn = 0.0f;
  if (psmap) psmap->FindPrice(pszKey, pszMarket, brokerid.c_str(), dfreturn);
  return dfreturn;
}

CBondInfo* CSSVContainer::GetBond(const std::string& sBondKey,
                                  const std::string& sMarket) {
  return GetBond(sBondKey + "." + sMarket);
}

CBondInfo* CSSVContainer::GetBond(const std::string& sCombBondKey) {
  void* pArrayID = nullptr;
  PrepareMap();
  if (m_keymap.Lookup(sCombBondKey.c_str(), pArrayID)) {
    uint64_t uArrayID = (uint64_t)pArrayID;
    return GetBondByOwnIndex((int)uArrayID);
  }

  return nullptr;
}

CBondInfo* CSSVContainer::GetBond(int nBondIndex) {
  if (nBondIndex < 0 || nBondIndex >= CBondContainer::instance().GetSize()) {
    return nullptr;
  }

  return CBondContainer::instance().GetBond(nBondIndex);
}

CBondInfo* CSSVContainer::GetBondByOwnIndex(int nIndex) {
  if (nIndex < 0 || nIndex >= GetSize()) return nullptr;

  return CBondContainer::instance().GetBond(GetBondIndexByOwnIndex(nIndex));
}

int CSSVContainer::GetBondIndexByOwnIndex(int nIndex) {
  if (nIndex < 0 || nIndex >= GetSize()) return -1;

  return m_array_result[nIndex];
}

// 删除容器中的债券
void CSSVContainer::DelBondVector(char* BondKey, BLHCONDITION& condStr,
                                  bool bAll) {
  if (BondKey == nullptr) {
    return;
  }

  CBondContainer& gc = CBondContainer::instance();
  size_t nSize = m_array_result.size();
  std::vector<int>::iterator l_iter = m_array_result.begin();
  std::vector<int>::iterator l_EndITer = m_array_result.end();
  std::vector<int>::iterator l_delIter = m_array_result.end();
  for (; l_iter != l_EndITer; ++l_iter) {
    const CBondInfo& info = gc.ElementAtR(*l_iter);
    if (strcmp(info.GetCombBondKey(), BondKey) == 0) {
      l_delIter = l_iter;
      break;
    }
  }
  if (l_delIter != l_EndITer) {
    m_array_result.erase(l_delIter);
    m_brokevec.m_vct.clear();

    SetMap();
    SetContent(condStr, bAll);
  }
}

bool CSSVContainer::AddBond(int nBondIndex) {
  if (nBondIndex < 0 || nBondIndex >= CBondContainer::instance().GetSize())
    return false;

  m_array_result.push_back(nBondIndex);

  return true;
}

bool CSSVContainer::AddBond(const char* sBondKey, const char* sListedMarket) {
  int nBondIndex =
      CBondContainer::instance().GetBondIndex(sBondKey, sListedMarket);
  return AddBond(nBondIndex);
}

bool CSSVContainer::RemoveBond(const char* sBondKey,
                               const char* sListedMarket) {
  int nBondIndex =
      CBondContainer::instance().GetBondIndex(sBondKey, sListedMarket);
  if (nBondIndex < 0 || nBondIndex >= CBondContainer::instance().GetSize())
    return false;

  std::vector<int>::iterator it;
  for (it = m_array_result.begin(); it != m_array_result.end(); it++) {
    if (*it == nBondIndex) {
      it = m_array_result.erase(it);
      return true;
      break;
    }
  }

  return false;
}

int CSSVContainer::GetAt(int nOwnIndex) {
  if (nOwnIndex < 0 || nOwnIndex >= (int)m_array_result.size()) {
    return -1;
  }

  return m_array_result[nOwnIndex];
}

bool CSSVContainer::RemoveBondByOwnIndex(int nOwnIndex) {
  if (nOwnIndex < 0 || nOwnIndex >= (int)m_array_result.size()) {
    return false;
  }

  m_array_result.erase(m_array_result.begin() + nOwnIndex);

  return true;
}

void CSSVContainer::GetDataCopy(IntArray& data) {
  std::lock_guard<std::mutex> locker(m_mutex);
  data.assign(m_array_result.begin(), m_array_result.end());
}

void CSSVContainer::SetDataSafe(std::vector<int>&& data) {
  std::lock_guard<std::mutex> locker(m_mutex);
  std::swap(m_array_result, data);
  data.clear();
  MarkMapDirty();
}

int CSSVContainer::GetBondIndex_Broker(int nOwnIndex2) {
  if (nOwnIndex2 < 0 || nOwnIndex2 >= (int)m_brokevec.m_vct.size()) {
    return -1;
  }

  return m_brokevec.m_vct[nOwnIndex2].m_nIndex;
}

int CSSVContainer::GetSize_Broker() { return m_brokevec.m_vct.size(); }

CBondInfo* CSSVContainer::GetBond_Broker(int nOwnIndex2) {
  int nBondIndex = GetBondIndex_Broker(nOwnIndex2);
  return CBondContainer::instance().GetBond(nBondIndex);
}

int CSSVContainer::CompareDouble(double dValue1, double dValue2) {
  if (fabs(dValue1 - dValue2) < 0.000001) {
    return 0;
  } else if (dValue1 > dValue2) {
    return 1;
  }

  return -1;
}

int CSSVContainer::GetRatingRank(const std::string& sRating) {
  return RatingRankManager::Get().GetRatingRank(sRating);
}

void CSSVContainer::SetSortFunction(int nSortKey, CSortFunction func) {
  m_mapSortFunc[nSortKey] = func;
}

bool CSSVContainer::CheckDiffPrice(const BLHCONDITION& Cond,
                                   const REPORT& report) {
  // true:表示通过检测,false:表示没有通过检测,不出现在最终结果集合中
  if (Cond.nBothFlg != 1)  // 忽略,全部通过检测
    return true;
  if (IsEmpty(Cond.sDiffPrice)) return true;

  // 当双边后edit内容不为空,必须要求bid,ofr都有值,且|bid-ofr|<=diff 才算通过;
  double bid = 0.0, ofr = 0.0;
  if (DecodeAsDouble(report.m_bidinfo.m_sPrice, bid) &&
      DecodeAsDouble(report.m_askinfo.m_sPrice, ofr)) {
    double diff = atof(Cond.sDiffPrice);
    return (bid - ofr) * 100.0 <= diff;
  }
  return false;
}

bool CSSVContainer::CheckBidVol(const BLHCONDITION& Cond,
                                const REPORT& report) {
  if (IsEmpty(Cond.sVolBid)) return true;

  if (IsEmpty(report.m_bidinfo.m_sVolume) ||
      strcmp(report.m_bidinfo.m_sVolume, "--") == 0)
    return false;

  double fFilterVol = atof(Cond.sVolBid);
  std::vector<std::string> vctDest;
  _SplitStr(vctDest, report.m_bidinfo.m_sVolume, "+");
  for (auto it = vctDest.begin(); it != vctDest.end(); ++it) {
    double fVolumn = atof(it->c_str());
    if (fabs(fVolumn) < 0.00001) continue;  // 去零
    if (Cond.nVolBpcCnd == 0)               // 0 表示[<= ], 1 表示[>= ]
    {
      if (fVolumn < fFilterVol + 0.000001) {
        return true;
      }
    } else {
      if (fVolumn > fFilterVol - 0.000001) {
        return true;
      }
    }
  }

  return false;
}

bool CSSVContainer::CheckOfrVol(const BLHCONDITION& Cond,
                                const REPORT& report) {
  if (IsEmpty(Cond.sVolOfr)) return true;

  if (IsEmpty(report.m_askinfo.m_sVolume) ||
      strcmp(report.m_askinfo.m_sVolume, "--") == 0)
    return false;

  double fFilterVol = atof(Cond.sVolOfr);
  std::vector<std::string> vctDest;
  _SplitStr(vctDest, report.m_askinfo.m_sVolume, "+");
  for (auto it = vctDest.begin(); it != vctDest.end(); ++it) {
    double fVolumn = atof(it->c_str());
    if (fabs(fVolumn) < 0.00001) continue;  // 去零
    if (Cond.nVolOpcCnd == 0)               // 0 表示[<= ], 1 表示[>= ]
    {
      if (fVolumn < fFilterVol + 0.000001) {
        return true;
      }
    } else {
      if (fVolumn > fFilterVol - 0.000001) {
        return true;
      }
    }
  }

  return false;
}

bool CSSVContainer::CheckSettlementLite(const BLHCONDITION& Cond,
                                        const REPORT& report) {
  if (Cond.nSettlement[0] == CBondContainer::StmAll) return true;
  if (strcmp(report.m_bidinfo.m_bp_status, "0") != 0 &&
      strcmp(report.m_askinfo.m_bp_status, "0") != 0)
    return false;
  return true;
}

bool CSSVContainer::CheckSettlement(const BLHCONDITION& Cond,
                                    const REPORT& report) {
  if (Cond.nSettlement[0] == CBondContainer::StmAll) return true;

  PRICE_SETTLEMENT_LIST lstBid, lstAsk;
  CBondContainer::DecodeSettlement(report.m_bidinfo, lstBid);
  CBondContainer::DecodeSettlement(report.m_askinfo, lstAsk);

  int sz = sizeof(Cond.nSettlement) / sizeof(int);
  for (int i = 0; i < sz; i++) {
    switch (Cond.nSettlement[i]) {
      case CBondContainer::StmT0:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x1)) return true;
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x1)) return true;
        }
        break;
      case CBondContainer::StmT1:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x2)) return true;
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x2)) return true;
        }
        break;
      case CBondContainer::StmFwd:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x4)) return true;
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x4)) return true;
        }
        break;
      case CBondContainer::StmSpot:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x3)) return true;
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x3)) return true;
        }
        break;
      case CBondContainer::StmNone:
      default:
        break;
    }
  }

  return false;
}

void CSSVContainer::RebuildReportBySettlement(const BLHCONDITION& Cond,
                                              const REPORT& rptSource,
                                              REPORT& rptDest) {
#define _AddVolumn(valid, vol1, vol2, desc1, desc2) \
  {                                                 \
    if (!valid) {                                   \
      memset(vol2, 0, sizeof(vol2));                \
      memset(desc2, 0, sizeof(desc2));              \
      FIELDCOPY(vol2, vol1);                        \
      strncat(desc2, vol1, _TRUNCATE);              \
      if (strlen(desc1) > 0) {                      \
        strncat(desc2, "(", _TRUNCATE);             \
        strncat(desc2, desc1, _TRUNCATE);           \
        strncat(desc2, ")", _TRUNCATE);             \
      }                                             \
      valid = true;                                 \
    } else {                                        \
      if (strlen(vol2) <= 0) {                      \
        FIELDCOPY(vol2, vol1);                      \
      } else {                                      \
        strncat(vol2, "+", _TRUNCATE);              \
        strncat(vol2, vol1, _TRUNCATE);             \
      }                                             \
      if (strlen(desc2) <= 0) {                     \
        FIELDCOPY(desc2, vol1);                     \
      } else {                                      \
        strncat(desc2, "+", _TRUNCATE);             \
        strncat(desc2, vol1, _TRUNCATE);            \
      }                                             \
      if (strlen(desc1) > 0) {                      \
        strncat(desc2, "(", _TRUNCATE);             \
        strncat(desc2, desc1, _TRUNCATE);           \
        strncat(desc2, ")", _TRUNCATE);             \
      }                                             \
    }                                               \
  };

  memcpy(&rptDest, &rptSource, sizeof(REPORT));
  if (Cond.nSettlement[0] == CBondContainer::StmAll) return;

  PRICE_SETTLEMENT_LIST lstBid, lstAsk;
  CBondContainer::DecodeSettlement(rptSource.m_bidinfo, lstBid);
  CBondContainer::DecodeSettlement(rptSource.m_askinfo, lstAsk);

  bool bBidValid = false, bOfrValid = false;
  int sz = sizeof(Cond.nSettlement) / sizeof(int);
  for (int i = 0; i < sz; i++) {
    switch (Cond.nSettlement[i]) {
      case CBondContainer::StmT0:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x1)) {
            _AddVolumn(bBidValid, it.m_vol, rptDest.m_bidinfo.m_sVolume,
                       it.m_desc, rptDest.m_bidinfo.m_description);
          }
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x1)) {
            _AddVolumn(bOfrValid, it.m_vol, rptDest.m_askinfo.m_sVolume,
                       it.m_desc, rptDest.m_askinfo.m_description);
          }
        }
        break;
      case CBondContainer::StmT1:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x2)) {
            _AddVolumn(bBidValid, it.m_vol, rptDest.m_bidinfo.m_sVolume,
                       it.m_desc, rptDest.m_bidinfo.m_description);
          }
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x2)) {
            _AddVolumn(bOfrValid, it.m_vol, rptDest.m_askinfo.m_sVolume,
                       it.m_desc, rptDest.m_askinfo.m_description);
          }
        }
        break;
      case CBondContainer::StmFwd:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x4)) {
            _AddVolumn(bBidValid, it.m_vol, rptDest.m_bidinfo.m_sVolume,
                       it.m_desc, rptDest.m_bidinfo.m_description);
          }
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x4)) {
            _AddVolumn(bOfrValid, it.m_vol, rptDest.m_askinfo.m_sVolume,
                       it.m_desc, rptDest.m_askinfo.m_description);
          }
        }
        break;
      case CBondContainer::StmSpot:
        for (auto& it : lstBid) {
          if (0 != (it.m_type & 0x3)) {
            _AddVolumn(bBidValid, it.m_vol, rptDest.m_bidinfo.m_sVolume,
                       it.m_desc, rptDest.m_bidinfo.m_description);
          }
        }
        for (auto& it : lstAsk) {
          if (0 != (it.m_type & 0x3)) {
            _AddVolumn(bOfrValid, it.m_vol, rptDest.m_askinfo.m_sVolume,
                       it.m_desc, rptDest.m_askinfo.m_description);
          }
        }
        break;
      case CBondContainer::StmNone:
      default:
        break;
    }
  }

  if (!bBidValid)  // 无筛选结果，清空报价
    memset(&rptDest.m_bidinfo, 0, sizeof(PRICE));
  else {
    if (strchr(rptDest.m_bidinfo.m_description, '(') == 0) {
      memset(rptDest.m_bidinfo.m_description, 0,
             sizeof(rptDest.m_bidinfo.m_description));
    }
  }

  if (!bOfrValid)
    memset(&rptDest.m_askinfo, 0, sizeof(PRICE));
  else {
    if (strchr(rptDest.m_askinfo.m_description, '(') == 0) {
      memset(rptDest.m_askinfo.m_description, 0,
             sizeof(rptDest.m_bidinfo.m_description));
    }
  }

  rptDest.m_create_time =
      max(rptDest.m_bidinfo.m_create_time, rptDest.m_askinfo.m_create_time);
  rptDest.m_time = max(rptDest.m_bidinfo.m_time, rptDest.m_askinfo.m_time);

  // BASSERT(rptDest.m_create_time == 0 || rptDest.m_create_time ==
  // rptSource.m_create_time);
  return;
}

bool CSSVContainer::IsExistBond(int nBondIndex) const {
  if (nBondIndex < 0 || nBondIndex >= CBondContainer::instance().GetSize()) {
    return false;
  }

  for (int i = 0; i < (int)m_array_result.size(); ++i) {
    if (nBondIndex == m_array_result[i]) {
      return true;
    }
  }

  return false;
}

bool CSSVContainer::IsExistBond(const char* sBondKey,
                                const char* sListedMarket) {
  if (sBondKey == nullptr || sListedMarket == nullptr) {
    return false;
  }

  string sCombBondKey = string(sBondKey) + "." + string(sListedMarket);
  void* pArrayID = nullptr;
  PrepareMap();
  if (m_keymap.Lookup(sCombBondKey.c_str(), pArrayID)) {
    return true;
  }

  return false;
}

bool CSSVContainer::IsNoBrokerBond(int nBondIndex) {
  int nNum = 0;
  std::vector<BrokerKey>::iterator itor = m_brokevec.m_vct.begin();
  for (; itor != m_brokevec.m_vct.end(); itor++) {
    if (nBondIndex == itor->m_nIndex) {
      ++nNum;
      return false;
    }
  }

  return nNum <= 0;
}

bool CSSVContainer::iRetrive(BLHCONDITION& condStr, bool bAll /* = false */,
                             CSSVContainer* pVC /* = nullptr */,
                             bool bSecondaryMarket /* = true */,
                             int nCallBackType /* = FCT_NULL */,
                             _BONDFILTER BondFilter /* = nullptr */) {
  if (!pVC) return iRetrive(condStr, bAll, nCallBackType, BondFilter);

  Clear();
  m_lcond = condStr;
  pVC->iRetrive(condStr, m_array_result, bSecondaryMarket, nCallBackType,
                BondFilter);

  SetMap();
  SetContent(condStr, bAll);
  return true;
}

bool CSSVContainer::iRetrive(BLHCONDITION& condStr,
                             std::vector<int>& array_result,
                             bool bSecondaryMarket /* = true */,
                             int nCallBackType /* = FCT_NULL */,
                             _BONDFILTER BondFilter /* = nullptr */) {
  std::lock_guard<std::mutex> locker(m_mutex);
  m_lcond = condStr;
  CBondContainer& gc = CBondContainer::instance();

  if (condStr.nBrokId[0] == 0 && strlen(condStr.sCompanyid) == 0) return false;

  std::vector<int>::iterator it;
  if (condStr.isAllin()) {
    for (it = m_array_result.begin(); it != m_array_result.end(); it++)
      array_result.push_back(*it);
    return true;
  }

  for (int n = 0; n < GetSize(); n++) {
    int nIndex = m_array_result[n];
    if (!gc.IsValidIndex(nIndex)) continue;
    bool bContinue = false;
    const CBondInfo& info = gc.ElementAtR(nIndex);

    do {
      if (condStr.nValid != 0 && !gc.IsBCQuoteValid(condStr, nIndex))  // 有报价
        break;
      if (condStr.nBothFlg != 0 &&
          !gc.IsBilateralPrice(condStr, nIndex))  // 双边报价
        break;
      if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
        break;
      if (condStr.nHasFlg != 0 && !gc.IsHasPrice(condStr, nIndex))  // 有效报价
        break;
      if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
        break;
      if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
        break;
      if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
        break;
      if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
        break;
      if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
        break;
      if (condStr.nOffset != 0 &&
          !gc.GetBondOffsetEstPrc(condStr, nIndex))  // 估值偏差
        break;
      if (!IsEmpty(condStr.sDiffPrice) &&
          !gc.GetDiffPrice(condStr, nIndex))  // BP差
        break;
      if ((strlen(condStr.sBPrice) != 0 || strlen(condStr.sBPriceEnd) != 0) &&
          !gc.GetBidCndPrice(condStr, nIndex))  // bid
        break;
      if ((strlen(condStr.sOPrice) != 0 || strlen(condStr.sOPriceEnd) != 0) &&
          !gc.GetOfrCndPrice(condStr, nIndex))  // ofr
        break;
      if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
          !info.CheckCommonUseType(condStr))  // 常用
        break;

      if (/*condStr.nType[0] != CBondContainer::BondAll &&*/ !info
              .CheckBondType(condStr, nCallBackType == CBondInfo::FCT_TYPE
                                          ? BondFilter
                                          : nullptr))  // 产品
        break;

      if (condStr.nGSMType[0] != CBondContainer::BondSC_All &&
          !info.CheckGSMBondType(condStr))  // 公募私募产品类型
        break;
      if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
          !gc.GetMultiLevel(condStr, info))  // 主体评级
        break;
      if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
          !gc.GetWarrType(condStr, info))  // 有担保
        break;
      if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
          !gc.GetMultiCouponType(condStr, info))  // 特殊分类
        break;
      if (condStr.nRight != CBondContainer::RightAll &&
          gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
        break;
      if (condStr.nRange[0] != CBondContainer::RangeAll &&
          !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
        break;
      if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
          !gc.GetMunicpType(condStr, info))  // 城投
        break;
      if (condStr.nInterbank != 0 && !info.IsInterbank())  // 银行间
        break;
      if (condStr.nExchange != 0 && !info.IsExchange())  // 交易所
        break;
      if (condStr.nInstion[0] != CBondContainer::InstAll &&
          !gc.GetMultiInstion(condStr, info))  // 机构类型
        break;
      if (condStr.szIssuer[0][0] != '\0' &&
          !info.CheckIssuer(condStr))  // 发行人
        break;
      if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
        break;
      if (condStr.szSector2021[0][0] != '\0' &&
          !info.CheckSector2021(condStr))  // 行业
        break;
      if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
        break;
      if (condStr.szSubType[0][0] != '\0' &&
          !info.CheckBontSubType(condStr))  // 细分
        break;
      if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
          !info.CheckDebtRating(condStr))  // 债项评级
        break;
      if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
          !info.CheckFinDebt(condStr))  // 金融债
        break;
      if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
          !gc.IsPlatformType(condStr, info))  // 平台债
        break;
      if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
          !gc.IsLocalBond(condStr, info))  // 地方债
        break;
      //  add  by  lbl  NCD
      if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
          !info.CheckNCDRating(condStr))  // NCD
        break;
      // end
      if (condStr.nIssueYear[0] != 0 &&
          !info.CheckIssueYear(condStr))  // 发行年份
        break;
      if (condStr.nStateType != 0 &&
          !gc.GetStateType(
              condStr, info))  // 0=全部，1=今日簿记建档，2=当日发行，3=当日公告
        break;
      // if(condStr.nUnderwriter != 0 && info.m_sIsUnderwriter!='1')
      //	break;
      if (strlen(condStr.szIssueDateB) != 0 &&
          strlen(condStr.szIssueDateE) != 0 &&
          !gc.GetIssueStartDate(condStr, info))  // 发行日期
        break;
      if (condStr.szUnderwriter[0] != 0 &&
          !info.CheckUnderwriter(condStr))  // 在团
        break;
      if (condStr.nCreditBond != 0 &&
          !info.IsCreditBond(condStr))  // 信用债,利率债
        break;
      if (!info.IsInDays(condStr)) break;
      if (condStr.nDeadLineRange[0] != CBondContainer::DL_RangeAll &&
          !gc.GetDeadLineRange(condStr, info))  // 期限筛选
        break;
      if (condStr.nExpireInHoliday == 1 &&
          info.IsExpireInHoliday())  // 不含假期
        break;
      bContinue = true;
    } while (0);
    if (bContinue) array_result.push_back(nIndex);
  }
  return true;
}

bool CSSVContainer::iRetrive(BLHCONDITION& condStr,
                             CBondInfo::MAP_BONDFILTER& mapBondFilter,
                             bool bAll /* = false */,
                             CSSVContainer* pVC /* = nullptr */,
                             bool bSecondaryMarket /* = true */) {
  if (!pVC) return RetrieveFromStatic(condStr, bAll);

  Clear();
  m_lcond = condStr;
  pVC->iRetrive(condStr, mapBondFilter, m_array_result, bSecondaryMarket);

  SetMap();
  SetContent(condStr, bAll);
  return true;
}

bool CSSVContainer::iRetrive(
    BLHCONDITION& condStr,
    CBondInfo::MAP_BONDFILTER& mapBondFilter /* = nullptr */,
    std::vector<int>& array_result, bool bSecondaryMarket /* = true */) {
  std::lock_guard<std::mutex> locker(m_mutex);
  m_lcond = condStr;
  CBondContainer& gc = CBondContainer::instance();

  if (condStr.nBrokId[0] == 0 && strlen(condStr.sCompanyid) == 0) return false;

  std::vector<int>::iterator it;
  if (condStr.isAllin()) {
    for (it = m_array_result.begin(); it != m_array_result.end(); it++)
      array_result.push_back(*it);
    return true;
  }

  for (int n = 0; n < GetSize(); n++) {
    int nIndex = m_array_result[n];
    if (!gc.IsValidIndex(nIndex)) continue;
    bool bContinue = false;
    const CBondInfo& info = gc.ElementAtR(nIndex);

    do {
      if (condStr.nValid != 0 && !gc.IsBCQuoteValid(condStr, nIndex))  // 有报价
        break;
      if (condStr.nBothFlg != 0 &&
          !gc.IsBilateralPrice(condStr, nIndex))  // 双边报价
        break;
      if (condStr.nNewFlg != 0 && !info.IsNewBond())  // 新发债
        break;
      if (condStr.nHasFlg != 0 && !gc.IsHasPrice(condStr, nIndex))  // 有效报价
        break;
      if (condStr.nMatFlg != 0 && info.IsExpireBond())  // 到期债券
        break;
      if (condStr.nASemi != 0 && !info.IsRebated())  // 一级半，新发债
        break;
      if (condStr.nMortgt != 0 && !info.IsMortgage())  // 可质押
        break;
      if (condStr.nCrosmk != 0 && !info.IsCrossMarket())  // 跨市场
        break;
      if (condStr.nEntrTyp != 0 && !gc.GetSOEenterType(condStr, info))  // 国企
        break;
      if (condStr.nOffset != 0 &&
          !gc.GetBondOffsetEstPrc(condStr, nIndex))  // 估值偏差
        break;
      if (!IsEmpty(condStr.sDiffPrice) &&
          !gc.GetDiffPrice(condStr, nIndex))  // BP差
        break;
      if ((strlen(condStr.sBPrice) != 0 || strlen(condStr.sBPriceEnd) != 0) &&
          !gc.GetBidCndPrice(condStr, nIndex))  // bid
        break;
      if ((strlen(condStr.sOPrice) != 0 || strlen(condStr.sOPriceEnd) != 0) &&
          !gc.GetOfrCndPrice(condStr, nIndex))  // ofr
        break;
      if (condStr.nCommonUse[0] != CBondContainer::CommAll &&
          !info.CheckCommonUseType(condStr))  // 常用
        break;

      if (condStr.nType[0] != CBondContainer::BondAll &&
          !CheckBondType(info, condStr, mapBondFilter))  // 产品
        break;

      if (condStr.nGSMType[0] != CBondContainer::BondSC_All &&
          !info.CheckGSMBondType(condStr))  // 公募私募产品类型
        break;
      if (condStr.nIssuerRating[0] != CBondContainer::RatingAll &&
          !gc.GetMultiLevel(condStr, info))  // 主体评级
        break;
      if (condStr.nWarrant[0] != CBondContainer::WarrAll &&
          !gc.GetWarrType(condStr, info))  // 有担保
        break;
      if (condStr.nCouponType[0] != CBondContainer::CouponAll &&
          !gc.GetMultiCouponType(condStr, info))  // 特殊分类
        break;
      if (condStr.nRight != CBondContainer::RightAll &&
          gc.GetRightType(condStr.nRight) != info.IsRight())  // 含权
        break;
      if (condStr.nRange[0] != CBondContainer::RangeAll &&
          !gc.GetMaturityRange(condStr, info, bSecondaryMarket))  // 剩余期限
        break;
      if (condStr.nMunicp[0] != CBondContainer::MunicAll &&
          !gc.GetMunicpType(condStr, info))  // 城投
        break;
      if (condStr.nInterbank != 0 && !info.IsInterbank())  // 银行间
        break;
      if (condStr.nExchange != 0 && !info.IsExchange())  // 交易所
        break;
      if (condStr.nInstion[0] != CBondContainer::InstAll &&
          !gc.GetMultiInstion(condStr, info))  // 机构类型
        break;
      if (condStr.szIssuer[0][0] != '\0' &&
          !info.CheckIssuer(condStr))  // 发行人
        break;
      if (condStr.szSector[0][0] != '\0' && !info.CheckSector(condStr))  // 行业
        break;
      if (condStr.szSector2021[0][0] != '\0' &&
          !info.CheckSector2021(condStr))  // 行业
        break;
      if (condStr.szArea[0][0] != '\0' && !info.CheckArea(condStr))  // 地区
        break;
      if (condStr.szSubType[0][0] != '\0' &&
          !info.CheckBontSubType(condStr))  // 细分
        break;
      if (condStr.nDebtRating[0] != CBondContainer::DRatingAll &&
          !info.CheckDebtRating(condStr))  // 债项评级
        break;
      if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll &&
          !info.CheckFinDebt(condStr))  // 金融债
        break;
      if (condStr.nPlatform[0] != CBondContainer::PlatforamAll &&
          !gc.IsPlatformType(condStr, info))  // 平台债
        break;
      if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll &&
          !gc.IsLocalBond(condStr, info))  // 地方债
        break;
      //  add by lbl
      if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll &&
          !info.CheckNCDRating(condStr))  // NCD
        break;
      // end
      if (condStr.nIssueYear[0] != 0 &&
          !info.CheckIssueYear(condStr))  // 发行年份
        break;
      if (condStr.nStateType != 0 &&
          !gc.GetStateType(
              condStr, info))  // 0=全部，1=今日簿记建档，2=当日发行，3=当日公告
        break;
      // if(condStr.nUnderwriter != 0 && info.m_sIsUnderwriter!='1')
      //	break;
      if (strlen(condStr.szIssueDateB) != 0 &&
          strlen(condStr.szIssueDateE) != 0 &&
          !gc.GetIssueStartDate(condStr, info))  // 发行日期
        break;
      if (condStr.szUnderwriter[0] != 0 &&
          !info.CheckUnderwriter(condStr))  // 在团
        break;
      if (condStr.nCreditBond != 0 &&
          !info.IsCreditBond(condStr))  // 信用债,利率债
        break;
      if (!info.IsInDays(condStr)) break;
      if (condStr.nDeadLineRange[0] != CBondContainer::DL_RangeAll &&
          !gc.GetDeadLineRange(condStr, info))  // 期限筛选
        break;
      if (condStr.nExpireInHoliday == 1 &&
          info.IsExpireInHoliday())  // 不含假期
        break;
      bContinue = true;
    } while (0);
    if (bContinue) array_result.push_back(nIndex);
  }
  return true;
}

bool CSSVContainer::CheckBondType(const CBondInfo& bi, BLHCONDITION& blh,
                                  CBondInfo::MAP_BONDFILTER& mapBondFilter) {
  CBondInfo::MAP_BONDFILTER::ITR itr =
      mapBondFilter.mapFilter.find(CBondInfo::FCT_TYPE);

  if (itr == mapBondFilter.mapFilter.end()) {
    return bi.CheckBondType(blh, nullptr);
  } else {
    return bi.CheckBondType(blh, itr->second);
  }
}

bool CSSVContainer::iRetrive(BLHCONDITION& condStr, bool bAll /* = false */,
                             int nCallBackType /* = CBondInfo::FCT_NULL */,
                             _BONDFILTER BondFilter /* = nullptr */) {
  Clear();
  m_lcond = condStr;
  CBondContainer::instance().iRetrive(condStr, m_array_result, true,
                                      nCallBackType, BondFilter);
  SetMap();

  SetContent(condStr, bAll);
  return true;
}

void CSSVContainer::ResetArrayResult() {
  // #ifdef DEBUG
  //  	{
  //  		set<int> setBondIndex1, setBondIndex2;
  //  		for (size_t i = 0; i < m_brokevec.m_vct.size(); ++i)
  //  		{
  //  			setBondIndex1.insert(m_brokevec.m_vct[i].m_nIndex);
  //  		}
  //
  //  		for (size_t i = 0; i < m_array_result.size(); ++i)
  //  		{
  //  			setBondIndex2.insert(m_array_result[i]);
  //  		}
  //
  //  		if (setBondIndex1 != setBondIndex2)
  //  		{
  //  			LOGDEBUG("m_brokevec.m_vct is not match
  //  m_array_result");
  //  		}
  //  		else
  //  		{
  //  			return;
  //  		}
  //
  //  	}
  // #endif // DEBUG

  // 从m_brokevec.m_vct数据中，重置基础数据
  m_array_result.clear();
  MarkMapDirty();
  set<int> setInt;
  for (size_t i = 0; i < m_brokevec.m_vct.size(); ++i) {
    if (setInt.insert(m_brokevec.m_vct[i].m_nIndex).second) {
      m_array_result.push_back(m_brokevec.m_vct[i].m_nIndex);
    }
  }
}
